290 lines
6.9 KiB
JavaScript
290 lines
6.9 KiB
JavaScript
// Copyright 2021 99cloud
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import {
|
|
isNil,
|
|
isString,
|
|
isUndefined,
|
|
isNumber,
|
|
isNaN,
|
|
isArray,
|
|
unescape,
|
|
} from 'lodash';
|
|
import { customAlphabet } from 'nanoid';
|
|
|
|
import { getLocalTimeStr, getKeepTime, getSinceTime } from './time';
|
|
import { SIZE_VALUE, MILLISECOND_IN_TIME_UNIT } from './constants';
|
|
|
|
/**
|
|
* format size, output the value with unit
|
|
* @param {Number} size - the number need to be format
|
|
*/
|
|
export const formatSize = (size, start = 0) => {
|
|
const divisor = 1024;
|
|
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'BB'];
|
|
let index = isNumber(start) ? start : 0;
|
|
if (!isNumber(size) || isNaN(size)) {
|
|
return size || '-';
|
|
}
|
|
while (size >= divisor && index < units.length - 1) {
|
|
size = parseFloat(size / divisor).toFixed(2);
|
|
index += 1;
|
|
}
|
|
if (index === 0) {
|
|
size = parseInt(size, 10);
|
|
}
|
|
return `${size} ${units[index]}`;
|
|
};
|
|
|
|
/**
|
|
* format used time(ms).
|
|
* @param {Number} ms
|
|
*/
|
|
export const formatUsedTime = (ms) => {
|
|
const { s, m, h, d, w } = MILLISECOND_IN_TIME_UNIT;
|
|
if (ms < s) {
|
|
return `${ms} ms`;
|
|
}
|
|
if (ms <= m) {
|
|
return `${parseFloat(ms / s).toFixed(2)} s`;
|
|
}
|
|
if (ms <= h) {
|
|
return `${parseFloat(ms / m).toFixed(2)} min`;
|
|
}
|
|
if (ms <= d) {
|
|
return `${parseFloat(ms / h).toFixed(2)} h`;
|
|
}
|
|
if (ms <= w) {
|
|
return `${parseFloat(ms / d).toFixed(2)} d`;
|
|
}
|
|
return `${parseFloat(ms / w).toFixed(2)} w`;
|
|
};
|
|
|
|
export const generateId = (length) =>
|
|
customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', length || 6)();
|
|
|
|
export const getQueryString = (params) =>
|
|
Object.keys(params)
|
|
.filter((key) => params[key])
|
|
.map((key) => `${key}=${params[key]}`)
|
|
.join('&');
|
|
|
|
export const getYesNo = (input) => (input ? t('Yes') : t('No'));
|
|
|
|
export const getGBValue = (input) => {
|
|
const gb = 1024;
|
|
if (isNaN(input) || isNil(input) || !input || !isNumber(input)) {
|
|
return 0;
|
|
}
|
|
return parseFloat(Number(input / gb).toFixed(2));
|
|
};
|
|
|
|
export const getNoValue = (input, def) => {
|
|
if (
|
|
isNil(input) ||
|
|
isUndefined(input) ||
|
|
(isString(input) && input.trim() === '')
|
|
) {
|
|
return def || '-';
|
|
}
|
|
return input;
|
|
};
|
|
|
|
export const firstUpperCase = (str) => {
|
|
if (!isString(str) || str === '') {
|
|
return str;
|
|
}
|
|
const [first, ...rest] = str;
|
|
return first.toUpperCase() + rest.join('');
|
|
};
|
|
|
|
export const bytesFitler = (input) => {
|
|
const { kb, mb, gb, tb } = SIZE_VALUE;
|
|
if (isNaN(input) || isUndefined(input) || input === null || input < 0) {
|
|
return '';
|
|
}
|
|
if (input >= tb) {
|
|
const size = Number(input / tb).toFixed(2);
|
|
return t('{ size } TB', { size });
|
|
}
|
|
if (input >= gb) {
|
|
const size = Number(input / gb).toFixed(2);
|
|
return t('{ size } GB', { size });
|
|
}
|
|
if (input >= mb) {
|
|
const size = Number(input / mb).toFixed(2);
|
|
return t('{ size } MB', { size });
|
|
}
|
|
if (input >= kb) {
|
|
const size = Number(input / kb).toFixed(2);
|
|
return t('{ size } KB', { size });
|
|
}
|
|
const size = Math.floor(input);
|
|
return t('{ size } bytes', { size });
|
|
};
|
|
|
|
export const uppercaseFilter = (input) => {
|
|
if (!input || !isString(input)) {
|
|
return '-';
|
|
}
|
|
return input.toUpperCase();
|
|
};
|
|
|
|
export const toLocalTimeFilter = (input) => {
|
|
if (!input) {
|
|
return '-';
|
|
}
|
|
|
|
let dateTime;
|
|
if (typeof input === 'number') {
|
|
dateTime = new Date(input);
|
|
} else {
|
|
if (!/\+00:00$/.test(input)) {
|
|
if (!/Z$/.test(input)) {
|
|
input = input.concat('Z');
|
|
}
|
|
}
|
|
|
|
dateTime = new Date(input);
|
|
}
|
|
|
|
let format = '%y-%m-%d %H:%M:%S';
|
|
const f = {
|
|
y: dateTime.getYear() + 1900,
|
|
m: dateTime.getMonth() + 1,
|
|
d: dateTime.getDate(),
|
|
H: dateTime.getHours(),
|
|
M: dateTime.getMinutes(),
|
|
S: dateTime.getSeconds(),
|
|
};
|
|
Object.keys(f).forEach((timePart) => {
|
|
format = format.replace(
|
|
`%${timePart}`,
|
|
f[timePart] < 10 ? `0${f[timePart]}` : f[timePart]
|
|
);
|
|
});
|
|
return format;
|
|
};
|
|
|
|
export const renderFilterMap = {
|
|
sinceTime: getSinceTime,
|
|
keepTime: getKeepTime,
|
|
yesNo: getYesNo,
|
|
GBValue: getGBValue,
|
|
noValue: getNoValue,
|
|
bytes: bytesFitler,
|
|
uppercase: uppercaseFilter,
|
|
formatSize,
|
|
toLocalTime: toLocalTimeFilter,
|
|
toLocalTimeMoment: getLocalTimeStr,
|
|
};
|
|
|
|
export const getOptions = (obj) =>
|
|
Object.keys(obj).map((key) => ({
|
|
label: obj[key],
|
|
value: key,
|
|
key,
|
|
}));
|
|
|
|
export const getYesNoList = () => [
|
|
{ value: true, label: t('Yes') },
|
|
{ value: false, label: t('No') },
|
|
];
|
|
|
|
/**
|
|
* 生成一个从 start 到 end 的连续数组,左闭右开,
|
|
* @param start
|
|
* @param end
|
|
*/
|
|
export const generateArray = (start, end) => {
|
|
const length = Math.abs(start - end);
|
|
return Array.from(new Array(length).keys()).map((i) => i + start);
|
|
};
|
|
|
|
export const NoSetValue = 'noSelect';
|
|
|
|
export const getOptionsWithNoset = (options) => {
|
|
const newOptions = isArray(options) ? options : getOptions(options);
|
|
const noSet = {
|
|
value: NoSetValue,
|
|
label: t('Not select'),
|
|
};
|
|
return [noSet, ...newOptions];
|
|
};
|
|
|
|
export const computePercentage = function (used, total, digits = 2) {
|
|
if (used === 0) {
|
|
return 0;
|
|
}
|
|
return parseFloat(
|
|
((parseFloat(used) / parseFloat(total)) * 100).toFixed(digits)
|
|
);
|
|
};
|
|
|
|
export const groupArray = (arr, subGroupLength) => {
|
|
let index = 0;
|
|
const newArray = [];
|
|
while (index < arr.length) {
|
|
newArray.push(arr.slice(index, (index += subGroupLength)));
|
|
}
|
|
return newArray;
|
|
};
|
|
|
|
export const updateObjToAddSelectArray = (value = {}) => {
|
|
const values = [];
|
|
Object.keys(value).forEach((it, index) => {
|
|
values.push({
|
|
index,
|
|
value: { key: it, value: value[it] },
|
|
});
|
|
});
|
|
return values;
|
|
};
|
|
|
|
export const updateAddSelectValueToObj = (arr = []) => {
|
|
const obj = {};
|
|
arr.forEach((it) => {
|
|
const { key, value } = it.value;
|
|
if ((isString(value) && value) || !isString(value)) {
|
|
obj[key] = value;
|
|
}
|
|
});
|
|
return obj;
|
|
};
|
|
|
|
export const unescapeHtml = (message) => {
|
|
if (isString(message)) {
|
|
return unescape(message);
|
|
}
|
|
return message;
|
|
};
|
|
|
|
export const isAdminPage = (url) => url && url.indexOf('admin') >= 0;
|
|
|
|
export const isUserCenterPage = (url) =>
|
|
url && (url === '/user' || url.startsWith('/user/'));
|
|
|
|
export const allSettled = (promises) => {
|
|
if (!Promise.allSettled) {
|
|
return Promise.all(
|
|
promises.map((promise) =>
|
|
promise
|
|
.then((value) => ({ status: 'fulfilled', value }))
|
|
.catch((reason) => ({ status: 'rejected', reason }))
|
|
)
|
|
);
|
|
}
|
|
return Promise.allSettled(promises);
|
|
};
|