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.
219 lines
6.2 KiB
219 lines
6.2 KiB
/**
|
|
* 辅助函数
|
|
*/
|
|
import dayjs from 'dayjs';
|
|
import gcoord from "gcoord";
|
|
|
|
/**
|
|
* 等待异步结果
|
|
* @param checker 检测函数,返回值为truthy时表示得到想要的结果,否则反之
|
|
* @param timeout 指定时间内没有得到想要的结果则超时
|
|
*/
|
|
export function until(checker = () => true, timeout = 2000) {
|
|
return new Promise((resolve) => {
|
|
let pollingTimer = null;
|
|
|
|
const timeoutTimer = setTimeout(() => {
|
|
clearInterval(pollingTimer);
|
|
resolve(false);
|
|
}, timeout);
|
|
|
|
pollingTimer = setInterval(() => {
|
|
const result = checker();
|
|
if (result) {
|
|
clearTimeout(timeoutTimer);
|
|
clearInterval(pollingTimer);
|
|
resolve(result);
|
|
}
|
|
}, 10);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 根据restful的uri构建实际url
|
|
* @param uri uri模版
|
|
* @param argv 插入到uri中的参数列表,按顺序插入
|
|
* @returns url
|
|
*/
|
|
export function buildURL(uri, ...argv) {
|
|
return uri.replace(/{\w+}|:[a-zA-Z]+/g, () => {
|
|
const res = argv.shift();
|
|
if (res === undefined) {
|
|
throw new Error('URI 参数不足');
|
|
}
|
|
return res;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 选取原object指定属性,构成新的object
|
|
* @param originObject
|
|
* @param pickKeys
|
|
*/
|
|
export function pick(originObject, pickKeys = []) {
|
|
const newObject = {};
|
|
pickKeys.forEach((key) => {
|
|
if (Object.prototype.hasOwnProperty.call(originObject, key)) {
|
|
newObject[key] = originObject[key];
|
|
}
|
|
});
|
|
return newObject;
|
|
}
|
|
|
|
/**
|
|
* 更新target对象的键值,使用source对象里的数据
|
|
* @param target
|
|
* @param source
|
|
*/
|
|
export function update(target, source) {
|
|
const result = { ...target };
|
|
Object.keys(target).forEach((key) => {
|
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
result[key] = source[key];
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 将对象的部分key重命名
|
|
* @param originObject 原始对象(也可以是相同结构的对象构成的数组)
|
|
* @param keysMapping 新keys映射(如{ name: 'username', sex: 'gender' },表示把原始对象中的name重命名为username、把sex重命名为gender,原始对象其他key不变)
|
|
* @returns {{}|*} 新对象
|
|
*/
|
|
export function renameKeys(originObject, keysMapping = {}) {
|
|
if (!Array.isArray(originObject)) {
|
|
const kvList = Object.keys(originObject).map((key) => {
|
|
const newKey = keysMapping[key] || key;
|
|
return { [newKey]: originObject[key] };
|
|
});
|
|
return Object.assign({}, ...kvList);
|
|
}
|
|
return originObject.map((obj) => renameKeys(obj, keysMapping));
|
|
}
|
|
|
|
/**
|
|
* 随机数
|
|
*/
|
|
export function rand(min, max, fraction = 0) {
|
|
const res = (Math.random() * ((max - min) + 1)) + min;
|
|
return res.toFixed(fraction) - 0;
|
|
}
|
|
|
|
/**
|
|
* 将input当着数字处理,若不是数字则返回代替字符
|
|
* @param input
|
|
* @param substitution
|
|
* @returns {string|number}
|
|
*/
|
|
export function numeric(input, substitution = '-') {
|
|
const type = typeof input;
|
|
if (type !== 'number' && type !== 'string') return substitution;
|
|
|
|
const output = Number(input);
|
|
return !Number.isNaN(output) ? output : substitution;
|
|
}
|
|
|
|
// 保留小数位(是整数则不保留)
|
|
export const toFixed = (num, digits = 2) => (Number(num || 0).toFixed(digits)) - 0;
|
|
|
|
|
|
export const falsyTo = (fv, to = '-') => (fv || fv === 0 ? fv : to);
|
|
/**
|
|
* 格式化时间戳
|
|
* @param timestamp
|
|
* @param format
|
|
* @returns {string}
|
|
*/
|
|
export function formatTime(timestamp, format = 'YYYY-MM-DD HH:mm:ss') {
|
|
return (timestamp || timestamp === 0) && dayjs(timestamp).isValid() ? dayjs(timestamp).format(format) : '-';
|
|
}
|
|
|
|
/**
|
|
* 将总秒数格式化为“x时y分z秒”形式
|
|
* @param sec
|
|
* @param precision
|
|
* @param isChinese
|
|
* @returns {string}
|
|
*/
|
|
export function popularTime(sec, precision = 0, isChinese = false) {
|
|
const { HOUR, MINUTE, SECOND } = isChinese ? { HOUR: '时', MINUTE: '分', SECOND: '秒' } : {
|
|
HOUR: 'h',
|
|
MINUTE: 'm',
|
|
SECOND: 's'
|
|
};
|
|
let remainingSec = sec;
|
|
const hours = Math.floor(remainingSec / 3600);
|
|
|
|
remainingSec -= hours * 3600;
|
|
const minutes = Math.floor(remainingSec / 60);
|
|
|
|
remainingSec -= minutes * 60;
|
|
|
|
return `${hours ? `${hours}${HOUR}` : ''}${minutes ? `${minutes}${MINUTE}` : ''}${remainingSec ? `${remainingSec.toFixed(precision)}${SECOND}` : ''}`;
|
|
}
|
|
|
|
/**
|
|
* 将秒转化为小时
|
|
* @param sec
|
|
* @returns {number}
|
|
*/
|
|
export function toHour(sec) {
|
|
return (sec / 3600).toFixed(2) - 0;
|
|
}
|
|
|
|
/**
|
|
* 对数组中的每个元素进行偏移计算,返回计算后的数组
|
|
* @param originArray 原数组(有数字构成)
|
|
* @param offsetArray 偏移量数组(与原数组元素一一对应)
|
|
* @returns {*[]} 计算后的新数组
|
|
*/
|
|
export function arrOffset(originArray = [], offsetArray = []) {
|
|
return originArray.map((item, index) => +item + (offsetArray[index] || 0));
|
|
}
|
|
|
|
/**
|
|
* 范围时间内,生成连续时间戳(按步长连续)
|
|
* @param startTs 起始时间戳
|
|
* @param endTs 结束时间戳
|
|
* @param step 步长(year | month | week | day | hour | minute | second | millisecond)
|
|
* @returns {*[]} 连续时间戳
|
|
*/
|
|
export function rangeTimestamps(startTs, endTs, step = 'day') {
|
|
const s = dayjs(startTs).startOf(step);
|
|
const eTs = dayjs(endTs).startOf(step).valueOf();
|
|
const result = [];
|
|
for (; s.valueOf() <= eTs;) {
|
|
result.push(s.valueOf());
|
|
s.add(1, step);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 计算出数组中最多的元素
|
|
* @param array
|
|
* @returns {*}
|
|
*/
|
|
export function mostCommonElement(array) {
|
|
return array.reduce((max, element) => {
|
|
const count = array.filter((e) => e === element).length;
|
|
return count > array.filter((e) => e === max).length ? element : max;
|
|
}, '');
|
|
}
|
|
|
|
/**
|
|
* 将gps坐标,转换为国测局坐标
|
|
* @param point 经纬度构成的数组[经度, 纬度]
|
|
*/
|
|
export function GPS2GCJ(point) {
|
|
return gcoord.transform(point, gcoord.WGS84, gcoord.GCJ02);
|
|
}
|
|
|
|
/**
|
|
* 将国测局坐标,转换为gps坐标
|
|
* @param point 经纬度构成的数组[经度, 纬度]
|
|
*/
|
|
export function GCJ2GPS(point) {
|
|
return gcoord.transform(point, gcoord.GCJ02, gcoord.WGS84);
|
|
}
|
|
|