|
|
|
|
@ -1,3 +1,32 @@
|
|
|
|
|
if (!String.prototype.padStart) {
|
|
|
|
|
String.prototype.padStart = function padStart(targetLength, padString) {
|
|
|
|
|
targetLength = targetLength >> 0; // floor if number or convert non-number to 0;
|
|
|
|
|
padString = String(typeof padString !== 'undefined' ? padString : ' ');
|
|
|
|
|
if (this.length > targetLength) {
|
|
|
|
|
return String(this);
|
|
|
|
|
} else {
|
|
|
|
|
targetLength = targetLength - this.length;
|
|
|
|
|
if (targetLength > padString.length) {
|
|
|
|
|
padString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed
|
|
|
|
|
}
|
|
|
|
|
return padString.slice(0, targetLength) + String(this);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!Object.fromEntries) {
|
|
|
|
|
Object.fromEntries = function (entries) {
|
|
|
|
|
const obj = {};
|
|
|
|
|
for (let i = 0; i < entries.length; ++i) {
|
|
|
|
|
const entry = entries[i];
|
|
|
|
|
if (entry && entry.length === 2) {
|
|
|
|
|
obj[entry[0]] = entry[1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return obj;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @deprecated
|
|
|
|
|
* 废弃, 请使用 cloneDeep 或者 structuredClone
|
|
|
|
|
@ -6,6 +35,53 @@ export function copy(obj) {
|
|
|
|
|
return JSON.parse(JSON.stringify(obj));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function named(value) {
|
|
|
|
|
return function (target) {
|
|
|
|
|
target.definedName = value;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function formatCurrency(name) {
|
|
|
|
|
if (name === 'USD') {
|
|
|
|
|
return '$';
|
|
|
|
|
} else if (name === 'RMB') {
|
|
|
|
|
return '¥';
|
|
|
|
|
} else if (name === 'EUR') {
|
|
|
|
|
return '€';
|
|
|
|
|
} else if (name === 'GBP') {
|
|
|
|
|
return '£';
|
|
|
|
|
} else {
|
|
|
|
|
return name + ' ';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function formatPrice(price) {
|
|
|
|
|
return Math.ceil(price).toLocaleString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 千分符的金额转成数字,默认为0 */
|
|
|
|
|
export function price_to_number(price) {
|
|
|
|
|
const num_string = (price + '').replace(/,/g, '');
|
|
|
|
|
const number = parseFloat(num_string);
|
|
|
|
|
return isNaN(number) ? 0 : number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function formatPercent(number) {
|
|
|
|
|
return Math.round(number * 100) + '%';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function formatPercentToFloat(number) {
|
|
|
|
|
return parseFloat((number * 100).toFixed(2)) + '%';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @deprecated
|
|
|
|
|
* 废弃, 请使用 fixTo2Decimals
|
|
|
|
|
*/
|
|
|
|
|
export function percentToDecimal(number) {
|
|
|
|
|
return parseFloat(number) / 100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {Date} date
|
|
|
|
|
*/
|
|
|
|
|
@ -60,6 +136,28 @@ export function formatDatetime(date) {
|
|
|
|
|
|
|
|
|
|
return formatted;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {string | number | Date} date
|
|
|
|
|
*/
|
|
|
|
|
export function getWeek(date) {
|
|
|
|
|
// const weekday = new Date(date).toLocaleDateString("zh-CN", { weekday: "short" });
|
|
|
|
|
const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
|
|
|
|
const week = new Date(date).getDay();
|
|
|
|
|
return days[week];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function mixins(...list) {
|
|
|
|
|
return function (target) {
|
|
|
|
|
list.forEach((val) => {
|
|
|
|
|
const mixinObj = Object.create(val.prototype, {});
|
|
|
|
|
const name = Object.getPrototypeOf(mixinObj).constructor.name;
|
|
|
|
|
const camelCase = name.substr(0, 1).toLowerCase() + name.substr(1);
|
|
|
|
|
Object.assign(target.prototype, { [camelCase]: mixinObj });
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function splitArray2Parts(arr, size) {
|
|
|
|
|
const result = [];
|
|
|
|
|
for (let i = 0; i < arr.length; i += size) {
|
|
|
|
|
@ -113,6 +211,20 @@ export function prepareUrl(url) {
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
export const debounce = (func, wait, immediate) => {
|
|
|
|
|
var timeout;
|
|
|
|
|
return function () {
|
|
|
|
|
var context = this,
|
|
|
|
|
args = arguments;
|
|
|
|
|
clearTimeout(timeout);
|
|
|
|
|
if (immediate && !timeout) func.apply(context, args);
|
|
|
|
|
timeout = setTimeout(function () {
|
|
|
|
|
timeout = null;
|
|
|
|
|
if (!immediate) func.apply(context, args);
|
|
|
|
|
}, wait);
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function throttle(fn, delay, atleast) {
|
|
|
|
|
let timeout = null,
|
|
|
|
|
startTime = new Date();
|
|
|
|
|
@ -167,6 +279,25 @@ export function isNotEmpty(val) {
|
|
|
|
|
return val !== undefined && val !== null && val !== '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 推荐统一使用 isEmpty
|
|
|
|
|
* - **注意:**
|
|
|
|
|
* * 0, true, 'false' 不被判定为空
|
|
|
|
|
* @example
|
|
|
|
|
* emptyValue(0) => false
|
|
|
|
|
* - true if: [], {}, null, '', undefined, 'null', 'undefined', false,
|
|
|
|
|
* - false if: 0, true, 'false'
|
|
|
|
|
*/
|
|
|
|
|
export function emptyValue(a) {
|
|
|
|
|
if (a === '') return true; // 检验空字符串
|
|
|
|
|
if (a === 'null') return true; // 检验字符串类型的null
|
|
|
|
|
if (a === 'undefined') return true; // 检验字符串类型的 undefined
|
|
|
|
|
if (!a && a !== 0 && a !== '') return true; // 检验 undefined 和 null
|
|
|
|
|
if (Array.prototype.isPrototypeOf(a) && a.length === 0) return true; // 检验空数组
|
|
|
|
|
if (Object.prototype.isPrototypeOf(a) && Object.keys(a).length === 0) return true; // 检验空对象
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 数组排序
|
|
|
|
|
*/
|
|
|
|
|
@ -174,6 +305,10 @@ export const sortBy = (key) => {
|
|
|
|
|
return (a, b) => (getNestedValue(a, key) > getNestedValue(b, key) ? 1 : getNestedValue(b, key) > getNestedValue(a, key) ? -1 : 0);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const sortDescBy = (key) => {
|
|
|
|
|
return (a, b) => (a[key] < b[key] ? 1 : b[key] < a[key] ? -1 : 0);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Object排序keys
|
|
|
|
|
*/
|
|
|
|
|
@ -259,8 +394,7 @@ export function merge(...objects) {
|
|
|
|
|
* 数组分组
|
|
|
|
|
* - 相当于 lodash 的 _.groupBy
|
|
|
|
|
* @see https://www.lodashjs.com/docs/lodash.groupBy#_groupbycollection-iteratee_identity
|
|
|
|
|
* ECMAScript 2021 原生
|
|
|
|
|
* - Object.groupBy(items, callbackFn)
|
|
|
|
|
* - ECMAScript 2021 原生: Object.groupBy(items, callbackFn)
|
|
|
|
|
*/
|
|
|
|
|
export function groupBy(array = [], callback) {
|
|
|
|
|
return array.reduce((groups, item) => {
|
|
|
|
|
@ -422,8 +556,9 @@ export function objectMapper(input, keyMap) {
|
|
|
|
|
if (map) {
|
|
|
|
|
let value = input[key];
|
|
|
|
|
if (map.transform) value = map.transform(value);
|
|
|
|
|
if (typeof map === 'string') mappedObj[map] = value;
|
|
|
|
|
mappedObj[map.key || key] = value;
|
|
|
|
|
// mappedObj[map.key || map] = value;
|
|
|
|
|
// mappedObj[map.key || map] = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
@ -546,20 +681,6 @@ export const TagColorStyle = (tag, outerStyle = false) => {
|
|
|
|
|
return { color: `${color}`, ...outerStyleObj };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const debounce = (func, wait, immediate) => {
|
|
|
|
|
var timeout;
|
|
|
|
|
return function () {
|
|
|
|
|
var context = this,
|
|
|
|
|
args = arguments;
|
|
|
|
|
clearTimeout(timeout);
|
|
|
|
|
if (immediate && !timeout) func.apply(context, args);
|
|
|
|
|
timeout = setTimeout(function () {
|
|
|
|
|
timeout = null;
|
|
|
|
|
if (!immediate) func.apply(context, args);
|
|
|
|
|
}, wait);
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const removeFormattingChars = (str) => {
|
|
|
|
|
const regex = /[\r\n\t\v\f]/g;
|
|
|
|
|
str = str.replace(regex, ' ');
|
|
|
|
|
|