UNPKG

ts-api-core

Version:

Nodejs api framework core

588 lines 22.3 kB
"use strict"; 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