ts-api-core
Version:
Nodejs api framework core
588 lines • 22.3 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Utils = void 0;
/* eslint-disable @typescript-eslint/prefer-for-of */
/* eslint-disable no-plusplus */
const crypto = require("crypto");
const os = require("os");
const _uuid = require("node-uuid");
const error_1 = require("../base/error");
/** 无效日期时间 */
const __InvalidDate = '0000-00-00 00:00:00';
const __InvalidDateValue = new Date(0);
Number.prototype.toPrefixString = function (len) {
const v = Number(this).toString();
return v.length >= len ? v : '00000000000000000000'.substring(0, len - v.length) + v;
};
String.prototype.isEmpty = function () {
return !this;
};
String.prototype.toInt = function (defaultValue) {
const result = Number.parseInt(this === undefined ? '' : String(this), 10);
return Number.isNaN(result) ? Number(defaultValue) : result;
};
String.prototype.toFloat = function (defaultValue) {
const result = Number.parseFloat(this === undefined ? '' : String(this));
return Number.isNaN(result) ? Number(defaultValue) : result;
};
String.prototype.toArray = function () {
if (this) {
try {
const v = JSON.parse(String(this));
return Array.isArray(v) ? v : [v];
}
catch (e) {
return [this];
}
}
return [];
};
function getDateFormatValue(v, key, expand = true) {
switch (key) {
case "yyyy":
case "YYYY":
return v.getFullYear().toString();
break;
case "MM":
{
const m = v.getMonth() + 1;
return m < 10 ? '0' + m.toString() : m.toString();
}
break;
case "M": return (v.getMonth() + 1).toString();
case "DD":
case "dd":
{
const d = v.getDate();
return d < 10 ? '0' + d.toString() : d.toString();
}
break;
case "D":
case "d":
return v.getDate().toString();
break;
case "HH":
case "hh":
{
const h = v.getHours();
return h < 10 ? '0' + h.toString() : h.toString();
}
break;
case "H":
case "h":
return v.getHours().toString();
break;
case "mm":
{
const m = v.getMinutes();
return m < 10 ? '0' + m.toString() : m.toString();
}
break;
case "m": return v.getMinutes().toString();
case "ss":
{
const s = v.getSeconds();
return s < 10 ? '0' + s.toString() : s.toString();
}
break;
case "s": return v.getSeconds().toString();
case "SSS":
case "ZZZ":
{
const s = v.getMilliseconds();
return s < 10 ? '00' + s.toString() : (s < 100 ? '0' + s.toString() : s.toString());
}
break;
case "S": return v.getMilliseconds().toString();
default: {
if (expand !== true) {
return '';
}
const len = key.length;
let lastCode = key.charCodeAt(0);
let j = 0;
let i = 1;
let result = '';
while (i <= len) {
if (key.charCodeAt(i) !== lastCode || i === len) {
const k = key.substring(j, i);
const value = getDateFormatValue(v, k, false);
result += (value ? value : k);
j = i;
}
i++;
}
return result;
}
}
}
Date.prototype.format = function (format) {
const v = this;
const s = format || 'YYYY-MM-DD HH:mm:ss';
return s.replace(/[Y{3}y{3}M{2}D{2}d{2}m{2}H{2}h{2}s{2}S{3}Z{3}]+/gu, (k) => {
return getDateFormatValue(v, k);
});
};
Date.prototype.incSecond = function (v) {
return new Date(this.getTime() + 1000 * v);
};
Date.prototype.incMinutes = function (v) {
return new Date(this.getTime() + 60000 * v);
};
Date.prototype.incHours = function (v) {
return new Date(this.getTime() + 3600000 * v);
};
Date.prototype.incDay = function (v) {
return new Date(this.getTime() + 3600000 * 24 * v);
};
Array.prototype.convert = function (newItem, destArray) {
const result = destArray !== null && destArray !== void 0 ? destArray : [];
for (const item of this) {
result.push(newItem(item));
}
return result;
};
Array.prototype.distinct = function (key) {
const result = [];
for (const item of this) {
if (key ? result.filter(v => v[key] === item[key])[0] : result.filter(v => v === item)[0]) {
continue;
}
result.push(item);
}
return result;
};
Function.prototype.str = function (value) {
if (value === undefined || value === null) {
return '';
}
const type = typeof value;
if (type === 'string') {
return value;
}
else if (type === 'object') {
if (value instanceof Error) {
const data = { msg: value.message, stack: value.stack };
Object.assign(data, value);
return JSON.stringify(data);
}
return JSON.stringify(value);
}
return String(value);
};
Function.prototype.random = function (len = 4) {
const chars = "1234567890abcdefghijklmnopqrstuvwxyz";
const charsLen = chars.length;
let result = '';
for (let i = 0; i < len; i++) {
result += chars.charAt(Math.floor(Math.random() * charsLen));
}
return result;
};
Function.prototype.randomCode = function (len = 4) {
const chars = "123456789";
const charsLen = chars.length;
let result = '';
for (let i = 0; i < len; i++) {
result += chars.charAt(Math.floor(Math.random() * charsLen));
}
return result;
};
Function.prototype.toDate = function (value, defaultValue) {
const v = (value === undefined || value === null) ? defaultValue : value;
return v === undefined || v === null || v === 0 || v === __InvalidDate
? __InvalidDateValue
: v instanceof Date ? v : new Date(v);
};
/// -----------------------------------------------------------------------------
/// 公共函数和方法类
/// -----------------------------------------------------------------------------
/** 公共函数和方法 */
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
class Utils {
/**
* MD5加密
* @returns
* */
static md5(password) {
const md5 = crypto.createHash('md5');
return md5.update(password).digest('hex');
}
/** 当前时间戳, 毫秒 */
static currentTimeMillis() {
return new Date().getTime();
}
/** 将日期转为时间戳(毫秒),不传参数时返回当前时间戳 */
static getTime(date) {
const result = date === undefined
? new Date().getTime()
: (typeof date === 'number'
? date
: (typeof date === 'string'
? new Date(date).getTime()
: date.getTime()));
return Number.isNaN(result) ? 0 : result;
}
/** 延迟多少毫秒继续执行 */
static sleep(ms, data) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise(((resolve) => {
setTimeout(() => {
resolve(data);
}, ms);
}));
});
}
/** 获取ip地址 */
static getIPAddress() {
const interfaces = os.networkInterfaces();
for (const devName in interfaces) {
const address = interfaces[devName];
if (!address) {
continue;
}
for (let i = 0; i < address.length; i++) {
const alias = address[i];
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
return alias.address;
}
}
}
}
/** 获取枚举值列表 */
static enumValues(enumType) {
const values = [];
const keys = Object.keys(enumType);
keys.slice(keys.length / 2).forEach((key) => {
values.push(enumType[key]);
});
return values;
}
/** 获取枚举Key列表 */
static enumKeys(enumType) {
const keys = Object.keys(enumType);
return keys.slice(keys.length / 2);
}
/** 获取 uuid */
static uuid() {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
return _uuid.v4().replace(/-/gu, '');
}
/** 格式化日期时间, YYYY-MM-DD HH:mm:ss.SSS */
static formatDateTime(time, haveMilliseconds, invalidDateValue) {
const date = typeof time === 'number' ? new Date(time) : time;
const YY = date.getFullYear();
if (Number.isNaN(YY)) {
if (invalidDateValue === undefined) {
return __InvalidDate + (haveMilliseconds === true ? '.000' : '');
}
else {
return invalidDateValue;
}
}
const MM = this._twoNum(date.getMonth() + 1);
const DD = this._twoNum(date.getDate());
const hh = this._twoNum(date.getHours());
const mm = this._twoNum(date.getMinutes());
const ss = this._twoNum(date.getSeconds());
return YY.toString() + "-" + MM + "-" + DD + " " + hh + ":" + mm + ":" + ss + (haveMilliseconds === true ? "." + Utils._num2(date.getMilliseconds()) : '');
}
/** 格式化日期时间, HH:mm:ss.SSS */
static formatTime(time, haveMilliseconds) {
const date = typeof time === 'number' ? new Date(time) : time;
const hh = this._twoNum(date.getHours());
const mm = this._twoNum(date.getMinutes());
const ss = this._twoNum(date.getSeconds());
return hh + ":" + mm + ":" + ss + (haveMilliseconds === true ? "." + Utils._num2(date.getMilliseconds()) : '');
}
static getNowString(haveMilliseconds) {
return this.formatDateTime(this.currentTimeMillis(), haveMilliseconds);
}
static getTimeString(haveMilliseconds) {
return this.formatTime(this.currentTimeMillis(), haveMilliseconds);
}
/** 判断两个时间相差的小时数 */
static hourBetween(date1, date2) {
const result = this.milliseBetween(date1, date2);
return result / 3600000;
}
/** 判断两个时间相差的分钟数 */
static minutesBetween(date1, date2) {
const result = this.milliseBetween(date1, date2);
return result / 60000;
}
/** 判断两个时间相差的毫秒数 */
static milliseBetween(date1, date2) {
const d1 = typeof date1 === 'number' ? date1 : date1.getTime();
const d2 = typeof date2 === 'number' ? date2 : date2.getTime();
return d1 < d2 ? d2 - d1 : d1 - d2;
}
static parseInt(text, defaultValue) {
const result = Number.parseInt(text !== null && text !== void 0 ? text : '', 10);
return Number.isNaN(result) ? Number(defaultValue) : result;
}
static parseFloat(text, defaultValue) {
const result = Number.parseFloat(text !== null && text !== void 0 ? text : '');
return Number.isNaN(result) ? Number(defaultValue) : result;
}
/** 判断两个数字是否相等 */
static equalNumber(a1, a2) {
const v1 = typeof a1 === 'number' ? a1 : this.parseFloat(a1, 0);
const v2 = typeof a2 === 'number' ? a2 : this.parseFloat(a2, 0);
return v1 === v2 || (Number.isNaN(v1) && Number.isNaN(v2));
}
/** 检查是否是一个有效的日期时间 */
static invalidDate(value) {
if (value === undefined) {
return true;
}
const v = value instanceof Date ? value : new Date(value);
return Number.isNaN(v.getTime());
}
/** 处理一个日期时间数据,无效时返回 `defaultValue` (默认为0), 否则返回 `Date` 类型 */
static parseDate(value, defaultValue = 0) {
if (value === undefined) {
return defaultValue;
}
const v = value instanceof Date ? value : new Date(value);
return Number.isNaN(v.getTime()) ? defaultValue : v;
}
/** 指定日期时间增加 year 年 */
static dateIncYear(value, year, clearTime) {
const v = new Date(value);
if (year === 0 || Number.isNaN(v.getTime())) {
return v;
}
v.setFullYear(v.getFullYear() + year);
if (clearTime === true) {
v.setHours(23, 59, 59, 0);
}
else {
v.setDate(v.getDate() - 1);
}
return v;
}
/** 获取指定日期中当前日的时间范围 */
static timeRangeDay(date) {
const v = date ? (date instanceof Date ? date : new Date(date)) : new Date();
const yy = v.getFullYear();
const mm = v.getMonth();
const dd = v.getDate();
return [new Date(yy, mm, dd, 0, 0, 0, 0), new Date(yy, mm, dd, 23, 59, 59, 999)];
}
/** 获取指定日期中当前周的时间范围 */
static timeRangeWeek(date) {
const v = date ? (date instanceof Date ? date : new Date(date)) : new Date();
const dayOfWeek = v.getDay();
const yy = v.getFullYear();
const mm = v.getMonth();
const dd = v.getDate();
const weekStart = new Date(yy, mm, dd - dayOfWeek, 0, 0, 0, 0);
const weekEnd = new Date(yy, mm, dd + (6 - dayOfWeek), 23, 59, 59, 999);
return [weekStart, weekEnd];
}
/** 获取指定日期中当前月的时间范围 */
static timeRangeMonth(date) {
const v = date ? (date instanceof Date ? date : new Date(date)) : new Date();
const YY = v.getFullYear();
const MM = v.getMonth();
return [new Date(YY, MM, 1, 0, 0, 0, 0), new Date(YY, MM + 1, 0, 23, 59, 59, 999)];
}
/**
* 获取指定日期下的时间范围
* @param type 0 指定的时间,1 今日,2 本周,3 本月
* @param date 指定的日期,默认为当前时间
* @param beginTime
* @param endTime
*/
static getDateRange(type = 1, date, beginTime, endTime) {
switch (type) {
case 0:
return [
beginTime ? (beginTime instanceof Date ? beginTime : new Date(beginTime)) : new Date(),
endTime ? (endTime instanceof Date ? endTime : new Date(endTime)) : new Date()
];
break;
case 1:
return this.timeRangeDay(date);
break;
case 2:
return this.timeRangeWeek(date);
break;
case 3:
return this.timeRangeMonth(date);
break;
default:
throw new error_1.SysError(`不支持的时间范围类型: ${type}`);
}
}
/**
* 转换数组为目标类型数组
* @param src 源数组
* @param newItem 转换回调函数
* @param destArray 输出的目标数组(如果设置,会追加转换后的数据)
* @returns 返回新的数组
*/
static convert(src, newItem, destArray) {
return src && Array.isArray(src) ? src.convert(newItem, destArray) : (destArray !== null && destArray !== void 0 ? destArray : []);
}
/**
* 将一个列表转化为树形列表, 列表数据需要本身支持转化成数型
* @param list 列表数据
* @param equalLevalItem 判断两个列表项是否同级且不相等的回调函数
* @param listFirstIsRoot 使用列表中的第1项作为树的root节点
* @param isRootItem 判断列表项是否为root节点的回调函数,listFirstIsRoot = false 时有效
* @param childrenField 列表项中,存放 children 列表的字段名称
* @param childrenMust 子列表字段是否必须存在,为 true 时,如果没有子列表,会将其设置为 []
* @param item 当前列表项, 调用者传 undefined
* @returns
*/
// eslint-disable-next-line max-params
static toTreeList(list, equalLevalItem, listFirstIsRoot = true, isRootItem, childrenField = "children", childrenMust = false, item) {
const children = [];
if (!list || list.length === 0) {
return children;
}
const handleChildren = (e) => {
let srcData = e[childrenField];
if (childrenMust && !srcData) {
srcData = [];
e[childrenField] = srcData;
}
const data = srcData ? srcData : [];
data.push(...this.toTreeList(list, equalLevalItem, listFirstIsRoot, undefined, childrenField, childrenMust, e));
if (!srcData && data.length > 0) {
e[childrenField] = data;
}
else if (data.length === 0 && !childrenMust) {
e[childrenField] = undefined;
}
};
let v = item;
if (v === undefined) {
if (listFirstIsRoot) {
v = list[0];
if (v[childrenField] === undefined) {
v[childrenField].children = [];
}
handleChildren(v);
children.push(v);
}
else {
// 找出 root 项
list.forEach((e, index) => {
if (isRootItem === null || isRootItem === void 0 ? void 0 : isRootItem(e, index)) {
handleChildren(e);
children.push(e);
}
});
}
return children;
}
list.filter((e) => {
if (equalLevalItem === null || equalLevalItem === void 0 ? void 0 : equalLevalItem(item, e)) {
return e;
} // 排除掉当前 item
}).forEach((e) => {
handleChildren(e);
children.push(e);
});
return children;
}
/**
* 数组去重
* @param array
* @param distinctKey
*/
static distinct(array, distinctKey) {
return array.distinct(distinctKey);
}
/**
* 将数组转换为 Markdown 表格
* @param data 数据源
* @param keyName 列标题
* @param columnReCount 重复列数(比如本身有2列,重复2次,就是6列,总行数就会只有三分之一)
* @param isVertical 重复列的时候,数据是横向还是竖向(默认为 `true` 竖向)
*/
static toMarkdownTable(data, keyName, columnReCount = 0, isVertical) {
if (data.length === 0 || columnReCount < 0) {
return '';
}
const keys = Object.keys(data[0]);
if (keys.length === 0) {
return '';
}
let result = '|';
let lineRow = '|';
for (var i = 0; i <= columnReCount; i++) {
keys.forEach(v => {
const name = keyName[v];
result += ' ' + (name ? name : v).replace('|', '\\|') + ' |';
lineRow += ' --- |';
});
}
result += '\n' + lineRow + '\n';
let j = 0;
const len = data.length;
const maxRow = Math.ceil(len / (columnReCount + 1));
while (j < maxRow) {
result += '|';
for (var i = 0; i <= columnReCount; i++) {
const index = isVertical === false ? j * (columnReCount + 1) + i : j + (i * maxRow);
if (index >= len) {
break;
}
const item = data[index];
keys.forEach(e => {
result += ' ' + this.str(item[e]).replace('|', '\\|') + ' |';
});
}
result += "\n";
j++;
}
return result;
}
/**
* 安静的Promise包裹器
* @param promise Promise
* @param onError 异常回调
* @returns
*/
static executeSilence(promise, onError) {
return __awaiter(this, void 0, void 0, function* () {
// @ts-expect-error
return promise
.then((data) => {
return [undefined, data];
})
.catch((err) => {
if (onError) {
onError(err);
}
return [err, undefined];
});
});
}
}
exports.Utils = Utils;
Utils._num2 = (v) => {
return v < 10 ? '00' + v.toString() : (v < 100 ? '0' + v.toString() : v.toString());
};
Utils._twoNum = (v) => {
return v < 10 ? '0' + v.toString() : v.toString();
};
/** 自定义日期类型输出格式 */
Date.prototype.toJSON = function () {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
return Utils.formatDateTime(this, false, '');
};
//# sourceMappingURL=utils.js.map