享飞-小程序
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

/**
* 辅助函数
*/
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);
}