|
|
|
/**
|
|
|
|
* Author: Fu Guobin
|
|
|
|
* Date: 2020/06/28
|
|
|
|
* Last Modified by: Fu Guobin
|
|
|
|
* Last Modified time: 2023/05/29
|
|
|
|
* Copyright:Daniel(Fu Guobin)
|
|
|
|
* Description:封装函数工具
|
|
|
|
*/
|
|
|
|
|
|
|
|
import { useTransition, TransitionPresets } from '@vueuse/core';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 校验数据类型
|
|
|
|
* typeOf('type')
|
|
|
|
*/
|
|
|
|
export function typeOf(obj: any) {
|
|
|
|
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* uuid
|
|
|
|
*/
|
|
|
|
export function uuid() {
|
|
|
|
const temp_url = URL.createObjectURL(new Blob());
|
|
|
|
const uuid = temp_url.toString();
|
|
|
|
URL.revokeObjectURL(temp_url); //释放这个url
|
|
|
|
return uuid.substring(uuid.lastIndexOf('/') + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 随机数
|
|
|
|
*/
|
|
|
|
export function numberRandom(min: number, max: number) {
|
|
|
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 值之间的过度
|
|
|
|
* @param {number} num 需要过度的数值
|
|
|
|
* @param {number} duration 过渡时间
|
|
|
|
*/
|
|
|
|
export function transitionNum(num: number, duration: number) {
|
|
|
|
const initial = ref(0);
|
|
|
|
const initialNum = useTransition(initial, {
|
|
|
|
duration: duration,
|
|
|
|
transition: TransitionPresets.easeInOutCubic
|
|
|
|
});
|
|
|
|
initial.value = num;
|
|
|
|
return initialNum;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 判断当前设备系统类型
|
|
|
|
* 1: ios
|
|
|
|
* 2: android
|
|
|
|
* 3: 其它
|
|
|
|
*/
|
|
|
|
export function getOSType() {
|
|
|
|
let u = navigator.userAgent;
|
|
|
|
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
|
|
|
|
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
|
|
|
|
if (isIOS) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (isAndroid) {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取两个数字之间的随机数
|
|
|
|
* @param {number} min 数字区间
|
|
|
|
* @param {number} max 数字区间
|
|
|
|
*/
|
|
|
|
export function random(min: number, max: number) {
|
|
|
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 计算平均值
|
|
|
|
* @param {number} args 数值(1, 2, 3, 4, 5)
|
|
|
|
*/
|
|
|
|
export function average(...args: any[]) {
|
|
|
|
return args.reduce((a, b) => a + b) / args.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 计算两个日期之间天数
|
|
|
|
* @param {Date} date 日期new Date("2023-05-18")
|
|
|
|
* @param {Date} otherDate 日期new Date("2023-07-18")
|
|
|
|
*/
|
|
|
|
export function diffDays(date: any, otherDate: any) {
|
|
|
|
return Math.ceil(Math.abs(date - otherDate) / (1000 * 60 * 60 * 24));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 确认一个数字是奇数还是偶数
|
|
|
|
* @param {number} num 数字
|
|
|
|
*/
|
|
|
|
export function isEven(num: number) {
|
|
|
|
return num % 2 === 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取一个随机的颜色值
|
|
|
|
*/
|
|
|
|
export function randomColor() {
|
|
|
|
return `#${Math.random().toString(16).slice(2, 8).padEnd(6, '0')}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 将RGB颜色转换为十六进制颜色值
|
|
|
|
* @param {number} rgb RGB(255, 255, 255)
|
|
|
|
*/
|
|
|
|
export function rgbToHex(r: number, g: number, b: number) {
|
|
|
|
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 将字符串转换为小驼峰
|
|
|
|
* @param {string} str ('background-color')
|
|
|
|
*/
|
|
|
|
export function toCamelCase(str: string) {
|
|
|
|
return str.trim().replace(/[-_\s]+(.)?/g, (_: any, c: string) => (c ? c.toUpperCase() : ''));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 单词首字母大写
|
|
|
|
* @param {string} str ('hello world')
|
|
|
|
*/
|
|
|
|
export function uppercaseWords(str: string) {
|
|
|
|
return str.replace(/^(.)|\s+(.)/g, c => c.toUpperCase());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 数组去重
|
|
|
|
* @param {array} arr 要去重的数组
|
|
|
|
*/
|
|
|
|
export function uniqueArray(arr = []) {
|
|
|
|
return [...new Set(arr)];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 数组对象根据字段去重
|
|
|
|
* @param {array} arr 要去重的数组
|
|
|
|
* @param {string} key 根据去重的字段名
|
|
|
|
*/
|
|
|
|
export function uniqueArrayObject(arr = [], key = 'id') {
|
|
|
|
if (arr.length === 0) return;
|
|
|
|
let list = [];
|
|
|
|
const map = {};
|
|
|
|
arr.forEach(item => {
|
|
|
|
if (!map[item[key]]) {
|
|
|
|
map[item[key]] = item;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
list = Object.values(map);
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取数组对象最后一个层级的数据
|
|
|
|
* @param {array} data 数组
|
|
|
|
*/
|
|
|
|
export function getLastLevelNode(data: any) {
|
|
|
|
if (data.length === 0) {
|
|
|
|
return null; // 数组为空,返回null或自定义默认值
|
|
|
|
}
|
|
|
|
|
|
|
|
const lastItem = data[data.length - 1]; // 获取数组的最后一个元素
|
|
|
|
|
|
|
|
if (lastItem.children && lastItem.children.length > 0) {
|
|
|
|
return getLastLevelNode(lastItem.children); // 继续递归调用
|
|
|
|
}
|
|
|
|
|
|
|
|
return lastItem; // 返回最后一个层级
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 获取数组对象第一个节点最后一个层级的数据
|
|
|
|
* @param {array} data 数组
|
|
|
|
*/
|
|
|
|
export function getFirstNodeLastLevel(data: any) {
|
|
|
|
if (data.length === 0) {
|
|
|
|
return null; // 数组为空,返回null或自定义默认值
|
|
|
|
}
|
|
|
|
|
|
|
|
const firstNode = data[0];
|
|
|
|
|
|
|
|
if (firstNode.children && firstNode.children.length > 0) {
|
|
|
|
return getFirstNodeLastLevel(firstNode.children);
|
|
|
|
}
|
|
|
|
|
|
|
|
return firstNode; // 返回第一个节点的最后一个层级的数据
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 数字补位
|
|
|
|
*/
|
|
|
|
export function numberPad(source: number, length = 2) {
|
|
|
|
let pre = '';
|
|
|
|
const negative = source < 0;
|
|
|
|
const string = String(Math.abs(source));
|
|
|
|
if (string.length < length) {
|
|
|
|
pre = new Array(length - string.length + 1).join('0');
|
|
|
|
}
|
|
|
|
return (negative ? '-' : '') + pre + string;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 保留小数点后几位
|
|
|
|
*/
|
|
|
|
export function cutNumber(number: number, no = 2) {
|
|
|
|
if (typeof number != 'number') {
|
|
|
|
number = Number(number);
|
|
|
|
}
|
|
|
|
return Number(number.toFixed(no));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 手机号脱敏
|
|
|
|
* @param phone
|
|
|
|
* @returns
|
|
|
|
*/
|
|
|
|
export function hidePhone(phone: string) {
|
|
|
|
return phone.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 身份证号脱敏
|
|
|
|
* @param idCard
|
|
|
|
* @returns
|
|
|
|
*/
|
|
|
|
export function hideIdCard(idCard: string) {
|
|
|
|
return idCard.replace(/^(.{6})(?:\d+)(.{4})$/, '$1****$2');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 验证canvas画布是否为空函数
|
|
|
|
* @param {object} canvas 画布对象
|
|
|
|
*/
|
|
|
|
export function isCanvasBlank(canvas: { width: number; height: number; toDataURL: () => string }) {
|
|
|
|
let blank = document.createElement('canvas'); //系统获取一个空canvas对象
|
|
|
|
blank.width = canvas.width;
|
|
|
|
blank.height = canvas.height;
|
|
|
|
return canvas.toDataURL() == blank.toDataURL(); //比较值相等则为空
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 时间段
|
|
|
|
* @param hours
|
|
|
|
* @returns
|
|
|
|
*/
|
|
|
|
export function timePeriod(hours: number) {
|
|
|
|
if (hours >= 3 && hours < 8) {
|
|
|
|
return '早安!';
|
|
|
|
} else if (hours >= 8 && hours < 11) {
|
|
|
|
return '上午好!';
|
|
|
|
} else if (hours >= 11 && hours < 13) {
|
|
|
|
return '中午好!';
|
|
|
|
} else if (hours >= 13 && hours < 17) {
|
|
|
|
return '下午好!';
|
|
|
|
} else if (hours >= 17 && hours < 23) {
|
|
|
|
return '晚上好!';
|
|
|
|
} else if (hours >= 23 && hours < 3) {
|
|
|
|
return '晚安!';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if an element has a class
|
|
|
|
* @param {HTMLElement} elm
|
|
|
|
* @param {string} cls
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
export function hasClass(ele: HTMLElement, cls: string) {
|
|
|
|
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add class to element
|
|
|
|
* @param {HTMLElement} elm
|
|
|
|
* @param {string} cls
|
|
|
|
*/
|
|
|
|
export function addClass(ele: HTMLElement, cls: string) {
|
|
|
|
if (!hasClass(ele, cls)) ele.className += ' ' + cls;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove class from element
|
|
|
|
* @param {HTMLElement} elm
|
|
|
|
* @param {string} cls
|
|
|
|
*/
|
|
|
|
export function removeClass(ele: HTMLElement, cls: string) {
|
|
|
|
if (hasClass(ele, cls)) {
|
|
|
|
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
|
|
|
|
ele.className = ele.className.replace(reg, ' ');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} path
|
|
|
|
* @returns {Boolean}
|
|
|
|
*/
|
|
|
|
export function isExternal(path: string) {
|
|
|
|
const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path);
|
|
|
|
return isExternal;
|
|
|
|
}
|