患者1.2
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
export declare const isUndefined: (input: any) => boolean;
|
||||
export declare const isPlainObject: (input: any) => boolean;
|
||||
export declare const isArray: (input: any) => boolean;
|
||||
export declare const isPrivateKey: (key: string) => boolean;
|
||||
export declare const isUrl: (url: string) => boolean;
|
||||
/**
|
||||
* 检测input类型是否为string
|
||||
* @param {*} input 任意类型的输入
|
||||
* @returns {Boolean} true->string / false->not a string
|
||||
*/
|
||||
export declare const isString: (input: any) => boolean;
|
||||
export declare const isBoolean: (input: any) => boolean;
|
||||
export declare const isNumber: (input: any) => boolean;
|
||||
export declare function formatTime(secondTime: number): string;
|
||||
export declare function formatTimeInverse(stringTime: string): number;
|
||||
export declare function isJSON(str: string): boolean;
|
||||
export declare const JSONToObject: (str: string) => any;
|
||||
/**
|
||||
* 重试函数, catch 时,重试
|
||||
* @param {Promise} promise 需重试的函数
|
||||
* @param {number} num 需要重试的次数
|
||||
* @param {number} time 间隔时间(s)
|
||||
* @returns {Promise<any>} im 接口的 response 原样返回
|
||||
*/
|
||||
export declare const retryPromise: (promise: Promise<any>, num?: number, time?: number) => Promise<any>;
|
||||
/**
|
||||
* web call engine 重复调用时的错误, 这种错误在 TUICallKit 应该忽略
|
||||
* @param {any} error 错误信息
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export declare function handleRepeatedCallError(error: any): boolean;
|
||||
/**
|
||||
* 设备无权限时的错误处理
|
||||
* @param {any} error 错误信息
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export declare function handleNoDevicePermissionError(error: any): boolean;
|
||||
export declare function performanceNow(): number;
|
||||
/**
|
||||
* 检测input类型是否为function
|
||||
* @param {*} input 任意类型的输入
|
||||
* @returns {Boolean} true->input is a function
|
||||
*/
|
||||
export declare const isFunction: (input: any) => boolean;
|
||||
export declare const getLanguage: () => string;
|
||||
export declare function noop(e: any): void;
|
||||
/**
|
||||
* Get the object type string
|
||||
* @param {*} input 任意类型的输入
|
||||
* @returns {String} the object type string
|
||||
*/
|
||||
export declare const getType: (input: any) => any;
|
||||
export declare function modifyObjectKey(obj: any, oldKey: any, newKey: any): any;
|
||||
@@ -0,0 +1,249 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.modifyObjectKey = exports.getType = exports.noop = exports.getLanguage = exports.isFunction = exports.performanceNow = exports.handleNoDevicePermissionError = exports.handleRepeatedCallError = exports.retryPromise = exports.JSONToObject = exports.isJSON = exports.formatTimeInverse = exports.formatTime = exports.isNumber = exports.isBoolean = exports.isString = exports.isUrl = exports.isPrivateKey = exports.isArray = exports.isPlainObject = exports.isUndefined = void 0;
|
||||
const index_1 = require("../const/index");
|
||||
const tuiGlobal_1 = __importDefault(require("../TUIGlobal/tuiGlobal"));
|
||||
const isUndefined = function (input) {
|
||||
return typeof input === index_1.NAME.UNDEFINED;
|
||||
};
|
||||
exports.isUndefined = isUndefined;
|
||||
const isPlainObject = function (input) {
|
||||
// 注意不能使用以下方式判断,因为IE9/IE10下,对象的__proto__是 undefined
|
||||
// return isObject(input) && input.__proto__ === Object.prototype;
|
||||
if (typeof input !== index_1.NAME.OBJECT || input === null) {
|
||||
return false;
|
||||
}
|
||||
const proto = Object.getPrototypeOf(input);
|
||||
if (proto === null) { // edge case Object.create(null)
|
||||
return true;
|
||||
}
|
||||
let baseProto = proto;
|
||||
while (Object.getPrototypeOf(baseProto) !== null) {
|
||||
baseProto = Object.getPrototypeOf(baseProto);
|
||||
}
|
||||
// 原型链第一个和最后一个比较
|
||||
return proto === baseProto;
|
||||
};
|
||||
exports.isPlainObject = isPlainObject;
|
||||
const isArray = function (input) {
|
||||
if (typeof Array.isArray === index_1.NAME.FUNCTION) {
|
||||
return Array.isArray(input);
|
||||
}
|
||||
return Object.prototype.toString.call(input).match(/^\[object (.*)\]$/)[1].toLowerCase() === index_1.NAME.ARRAY;
|
||||
};
|
||||
exports.isArray = isArray;
|
||||
const isPrivateKey = function (key) {
|
||||
return key.startsWith('_');
|
||||
};
|
||||
exports.isPrivateKey = isPrivateKey;
|
||||
const isUrl = function (url) {
|
||||
return /^(https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+)(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(url);
|
||||
};
|
||||
exports.isUrl = isUrl;
|
||||
/**
|
||||
* 检测input类型是否为string
|
||||
* @param {*} input 任意类型的输入
|
||||
* @returns {Boolean} true->string / false->not a string
|
||||
*/
|
||||
const isString = function (input) {
|
||||
return typeof input === index_1.NAME.STRING;
|
||||
};
|
||||
exports.isString = isString;
|
||||
const isBoolean = function (input) {
|
||||
return typeof input === index_1.NAME.BOOLEAN;
|
||||
};
|
||||
exports.isBoolean = isBoolean;
|
||||
const isNumber = function (input) {
|
||||
return (
|
||||
// eslint-disable-next-line
|
||||
input !== null &&
|
||||
((typeof input === index_1.NAME.NUMBER && !isNaN(input - 0)) || (typeof input === index_1.NAME.OBJECT && input.constructor === Number)));
|
||||
};
|
||||
exports.isNumber = isNumber;
|
||||
function formatTime(secondTime) {
|
||||
const hours = Math.floor(secondTime / 3600);
|
||||
const minutes = Math.floor((secondTime % 3600) / 60);
|
||||
const seconds = Math.floor(secondTime % 60);
|
||||
let callDurationStr = hours > 9 ? `${hours}` : `0${hours}`;
|
||||
callDurationStr += minutes > 9 ? `:${minutes}` : `:0${minutes}`;
|
||||
callDurationStr += seconds > 9 ? `:${seconds}` : `:0${seconds}`;
|
||||
return callDurationStr;
|
||||
}
|
||||
exports.formatTime = formatTime;
|
||||
function formatTimeInverse(stringTime) {
|
||||
const list = stringTime.split(':');
|
||||
return parseInt(list[0]) * 3600 + parseInt(list[1]) * 60 + parseInt(list[2]); // eslint-disable-line
|
||||
}
|
||||
exports.formatTimeInverse = formatTimeInverse;
|
||||
// Determine if it is a JSON string
|
||||
function isJSON(str) {
|
||||
if (typeof str === index_1.NAME.STRING) {
|
||||
try {
|
||||
const data = JSON.parse(str);
|
||||
if (data) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (error) {
|
||||
console.debug(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
exports.isJSON = isJSON;
|
||||
// Determine if it is a JSON string
|
||||
const JSONToObject = function (str) {
|
||||
if (!str || !isJSON(str)) {
|
||||
return str;
|
||||
}
|
||||
return JSON.parse(str);
|
||||
};
|
||||
exports.JSONToObject = JSONToObject;
|
||||
/**
|
||||
* 重试函数, catch 时,重试
|
||||
* @param {Promise} promise 需重试的函数
|
||||
* @param {number} num 需要重试的次数
|
||||
* @param {number} time 间隔时间(s)
|
||||
* @returns {Promise<any>} im 接口的 response 原样返回
|
||||
*/
|
||||
const retryPromise = (promise, num = 6, time = 0.5) => {
|
||||
let n = num;
|
||||
const func = () => promise;
|
||||
return func()
|
||||
.catch((error) => {
|
||||
if (n === 0) {
|
||||
throw error;
|
||||
}
|
||||
const timer = setTimeout(() => {
|
||||
func();
|
||||
clearTimeout(timer);
|
||||
n = n - 1;
|
||||
}, time * 1000);
|
||||
});
|
||||
};
|
||||
exports.retryPromise = retryPromise;
|
||||
// /**
|
||||
// * 节流函数(目前 TUICallKit 增加防重调用装饰器,该方法可删除)
|
||||
// * @param {Function} func 传入的函数
|
||||
// * @param {wait} time 间隔时间(ms)
|
||||
// */
|
||||
// export const throttle = (func: Function, wait: number) => {
|
||||
// let previousTime = 0;
|
||||
// return function () {
|
||||
// const now = Date.now();
|
||||
// const args = [...arguments];
|
||||
// if (now - previousTime > wait) {
|
||||
// func.apply(this, args);
|
||||
// previousTime = now;
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
/**
|
||||
* web call engine 重复调用时的错误, 这种错误在 TUICallKit 应该忽略
|
||||
* @param {any} error 错误信息
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function handleRepeatedCallError(error) {
|
||||
if ((error === null || error === void 0 ? void 0 : error.message.indexOf('is ongoing, please avoid repeated calls')) !== -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
exports.handleRepeatedCallError = handleRepeatedCallError;
|
||||
/**
|
||||
* 设备无权限时的错误处理
|
||||
* @param {any} error 错误信息
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function handleNoDevicePermissionError(error) {
|
||||
const { message } = error;
|
||||
if (message.indexOf('NotAllowedError: Permission denied') !== -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
exports.handleNoDevicePermissionError = handleNoDevicePermissionError;
|
||||
/*
|
||||
* 获取向下取整的 performance.now() 值
|
||||
* @export
|
||||
* @return {Number}
|
||||
*/
|
||||
function performanceNow() {
|
||||
// 在不支持 performance.now 的浏览器中,使用 Date.now()
|
||||
// 例如 ie 9,ie 10,避免加载 sdk 时报错
|
||||
if (!performance || !performance.now) {
|
||||
return Date.now();
|
||||
}
|
||||
return Math.floor(performance.now());
|
||||
}
|
||||
exports.performanceNow = performanceNow;
|
||||
/**
|
||||
* 检测input类型是否为function
|
||||
* @param {*} input 任意类型的输入
|
||||
* @returns {Boolean} true->input is a function
|
||||
*/
|
||||
const isFunction = function (input) {
|
||||
return typeof input === index_1.NAME.FUNCTION;
|
||||
};
|
||||
exports.isFunction = isFunction;
|
||||
/*
|
||||
* 获取浏览器语言
|
||||
* @export
|
||||
* @return {zh-cn | en}
|
||||
*/
|
||||
const getLanguage = () => {
|
||||
if (tuiGlobal_1.default.getInstance().isWeChat) {
|
||||
return 'zh-cn';
|
||||
}
|
||||
// @ts-ignore
|
||||
const lang = ((navigator === null || navigator === void 0 ? void 0 : navigator.language) || (navigator === null || navigator === void 0 ? void 0 : navigator.userLanguage) || '').substr(0, 2);
|
||||
let language = 'en';
|
||||
switch (lang) {
|
||||
case 'zh':
|
||||
language = 'zh-cn';
|
||||
break;
|
||||
case 'ja':
|
||||
language = 'ja_JP';
|
||||
break;
|
||||
default:
|
||||
language = 'en';
|
||||
}
|
||||
return language;
|
||||
};
|
||||
exports.getLanguage = getLanguage;
|
||||
function noop(e) { }
|
||||
exports.noop = noop;
|
||||
/**
|
||||
* Get the object type string
|
||||
* @param {*} input 任意类型的输入
|
||||
* @returns {String} the object type string
|
||||
*/
|
||||
const getType = function (input) {
|
||||
return Object.prototype.toString
|
||||
.call(input)
|
||||
.match(/^\[object (.*)\]$/)[1]
|
||||
.toLowerCase();
|
||||
};
|
||||
exports.getType = getType;
|
||||
// 修改对象键名
|
||||
function modifyObjectKey(obj, oldKey, newKey) {
|
||||
if (!obj.hasOwnProperty(oldKey)) {
|
||||
return obj;
|
||||
}
|
||||
const newObj = {};
|
||||
Object.keys(obj).forEach(key => {
|
||||
if (key === oldKey) {
|
||||
newObj[newKey] = obj[key];
|
||||
}
|
||||
else {
|
||||
newObj[key] = obj[key];
|
||||
}
|
||||
});
|
||||
return newObj;
|
||||
}
|
||||
exports.modifyObjectKey = modifyObjectKey;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export declare const IN_WX_MINI_APP: boolean;
|
||||
export declare const IN_UNI_NATIVE_APP: boolean;
|
||||
export declare const IN_MINI_APP: boolean;
|
||||
export declare const IN_UNI_APP: boolean;
|
||||
export declare const IN_BROWSER: boolean;
|
||||
export declare const APP_NAMESPACE: any;
|
||||
export declare const IS_H5: boolean;
|
||||
export declare const IS_PC: boolean;
|
||||
export declare const IS_WIN: any;
|
||||
export declare const IS_MAC: any;
|
||||
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.IS_MAC = exports.IS_WIN = exports.IS_PC = exports.IS_H5 = exports.APP_NAMESPACE = exports.IN_BROWSER = exports.IN_UNI_APP = exports.IN_MINI_APP = exports.IN_UNI_NATIVE_APP = exports.IN_WX_MINI_APP = void 0;
|
||||
// 在 uniApp 框架下,打包 H5、ios app、android app 时存在 wx/qq/tt/swan/my 等变量会导致引入 web sdk 环境判断失效
|
||||
// 小程序 getSystemInfoSync 返回的 fontSizeSetting 在 H5 和 app 中为 undefined,所以通过 fontSizeSetting 增强小程序环境判断
|
||||
// wx 小程序
|
||||
exports.IN_WX_MINI_APP = (typeof wx !== 'undefined' && typeof wx.getSystemInfoSync === 'function' && Boolean(wx.getSystemInfoSync().fontSizeSetting));
|
||||
// 用 uni-app 打包 native app,此时运行于 js core,无 window 等对象,此时调用 api 都得 uni.xxx,由于风格跟小程序类似,就归为 IN_MINI_APP 的一种
|
||||
exports.IN_UNI_NATIVE_APP = (typeof uni !== 'undefined' && typeof uni === 'undefined');
|
||||
exports.IN_MINI_APP = exports.IN_WX_MINI_APP || exports.IN_UNI_NATIVE_APP;
|
||||
exports.IN_UNI_APP = (typeof uni !== 'undefined');
|
||||
// 在 uniApp 框架下,由于客户打包 ios app、android app 时 window 不一定存在,所以通过 !IN_MINI_APP 进行判断
|
||||
// 非 uniApp 框架下,仍然通过 window 结合 IN_MINI_APP 进行判断,可兼容 Taro3.0+ 暴露 window 对象引起的 IN_BROWSER 判断失效问题
|
||||
exports.IN_BROWSER = (function () {
|
||||
if (typeof uni !== 'undefined') {
|
||||
return !exports.IN_MINI_APP;
|
||||
}
|
||||
return (typeof window !== 'undefined') && !exports.IN_MINI_APP;
|
||||
}());
|
||||
// 命名空间
|
||||
exports.APP_NAMESPACE = (function () {
|
||||
if (exports.IN_WX_MINI_APP) {
|
||||
return wx;
|
||||
}
|
||||
if (exports.IN_UNI_APP) {
|
||||
return uni;
|
||||
}
|
||||
return window;
|
||||
}());
|
||||
// eslint-disable-next-line no-mixed-operators
|
||||
const USER_AGENT = exports.IN_BROWSER && window && window.navigator && window.navigator.userAgent || '';
|
||||
const IS_ANDROID = /Android/i.test(USER_AGENT);
|
||||
const IS_WIN_PHONE = /(?:Windows Phone)/.test(USER_AGENT);
|
||||
const IS_SYMBIAN = /(?:SymbianOS)/.test(USER_AGENT);
|
||||
const IS_IOS = /iPad/i.test(USER_AGENT) || /iPhone/i.test(USER_AGENT) || /iPod/i.test(USER_AGENT);
|
||||
exports.IS_H5 = IS_ANDROID || IS_WIN_PHONE || IS_SYMBIAN || IS_IOS;
|
||||
exports.IS_PC = exports.IN_BROWSER && !exports.IS_H5;
|
||||
exports.IS_WIN = exports.IS_PC && USER_AGENT.includes('Windows NT');
|
||||
exports.IS_MAC = exports.IS_PC && USER_AGENT.includes('Mac');
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare function checkLocalMP3FileExists(src: string): Promise<boolean>;
|
||||
@@ -0,0 +1,33 @@
|
||||
"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.checkLocalMP3FileExists = void 0;
|
||||
function checkLocalMP3FileExists(src) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!src)
|
||||
return false;
|
||||
try {
|
||||
const response = yield new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('HEAD', src, true);
|
||||
xhr.onload = () => resolve(xhr);
|
||||
xhr.onerror = () => reject(xhr);
|
||||
xhr.send();
|
||||
});
|
||||
return response.status === 200 && response.getResponseHeader('Content-Type') === 'audio/mpeg';
|
||||
}
|
||||
catch (error) {
|
||||
console.warn(error);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.checkLocalMP3FileExists = checkLocalMP3FileExists;
|
||||
@@ -0,0 +1,2 @@
|
||||
declare const isEmpty: (input: any) => boolean;
|
||||
export default isEmpty;
|
||||
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const common_utils_1 = require("./common-utils");
|
||||
const isEmpty = function (input) {
|
||||
// Null and Undefined...
|
||||
if (input === null || typeof (input) === 'undefined')
|
||||
return true;
|
||||
// Booleans...
|
||||
if (typeof input === 'boolean')
|
||||
return false;
|
||||
// Numbers...
|
||||
if (typeof input === 'number')
|
||||
return input === 0;
|
||||
// Strings...
|
||||
if (typeof input === 'string')
|
||||
return input.length === 0;
|
||||
// Functions...
|
||||
if (typeof input === 'function')
|
||||
return input.length === 0;
|
||||
// Arrays...
|
||||
if (Array.isArray(input))
|
||||
return input.length === 0;
|
||||
// Errors...
|
||||
if (input instanceof Error)
|
||||
return input.message === '';
|
||||
// plain object
|
||||
if ((0, common_utils_1.isPlainObject)(input)) {
|
||||
// eslint-disable-next-line
|
||||
for (const key in input) {
|
||||
if (Object.prototype.hasOwnProperty.call(input, key)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
exports.default = isEmpty;
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/// <reference types="node" />
|
||||
/**
|
||||
* 定时器,功能:
|
||||
* 1. 支持定时执行回调 [1,n] 次,用于常规延迟、定时操作
|
||||
* @example
|
||||
* // 默认嵌套执行,count=0 无限次
|
||||
* timer.run(callback, {delay: 2000});
|
||||
* // count=1 等同于 原始setTimeout
|
||||
* timer.run(callback, {delay: 2000, count:0});
|
||||
* 2. 支持 RAF 执行回调,用于小流渲染,audio音量获取等任务,需要渲染频率稳定,支持页面退后台后,用 setTimeout 接管,最短 1s 执行一次
|
||||
* @example
|
||||
* // 默认60fps,可以根据单位时长换算,默认开启后台执行
|
||||
* timer.run('raf', callback, {fps: 60});
|
||||
* // 设置执行次数
|
||||
* timer.run('raf', callback, {fps: 60, count: 300, backgroundTask: false});
|
||||
* 3. 支持空闲任务执行回调, requestIdleCallback 在帧渲染的空闲时间执行任务,可以用于 storage 写入等低优先级的任务
|
||||
* @example
|
||||
* // 支持原生setInterval 但不推荐使用,定时任务推荐用 timeout
|
||||
* timer.run('interval', callback, {delay:2000, count:10})
|
||||
*/
|
||||
declare class Timer {
|
||||
static taskMap: Map<any, any>;
|
||||
static currentTaskID: number;
|
||||
static generateTaskID(): number;
|
||||
/**
|
||||
*
|
||||
* @param {string} taskName 'interval' 'timeout'
|
||||
* @param {function} callback
|
||||
* @param {object} options include:
|
||||
* @param {number} options.delay millisecond
|
||||
* @param {number} options.count 定时器回调执行次数,0 无限次 or n次
|
||||
* @param {boolean} options.backgroundTask 在页面静默后是否继续执行定时器
|
||||
*/
|
||||
static run(taskName: any, callback: any, options: any): any;
|
||||
/**
|
||||
* 定时循环执行回调函数
|
||||
* 可以指定循环的时间间隔
|
||||
* 可以指定循环次数
|
||||
* @param {object} taskItem
|
||||
* @param {function} callback
|
||||
* @param {*} delay
|
||||
* @param {*} count
|
||||
* @returns ID
|
||||
*/
|
||||
static interval(taskItem: any): NodeJS.Timer;
|
||||
/**
|
||||
* 延迟执行回调
|
||||
* count = 0,循环
|
||||
* count = n, 执行n次
|
||||
* @param {object} taskItem
|
||||
*
|
||||
*/
|
||||
static timeout(taskItem: any): NodeJS.Timeout;
|
||||
static hasTask(taskID: any): boolean;
|
||||
static clearTask(taskID: any): boolean;
|
||||
/**
|
||||
* 1. 如果已移除出定时队列,退出当前任务
|
||||
* 2. 如果当前任务已满足次数限制,则退出当前任务
|
||||
* @param {object} taskItem
|
||||
* @returns
|
||||
*/
|
||||
static isBreakLoop(taskItem: any): boolean;
|
||||
}
|
||||
export default Timer;
|
||||
@@ -0,0 +1,154 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/* eslint-disable */
|
||||
const common_utils_1 = require("./common-utils");
|
||||
const index_1 = require("../const/index");
|
||||
/**
|
||||
* 定时器,功能:
|
||||
* 1. 支持定时执行回调 [1,n] 次,用于常规延迟、定时操作
|
||||
* @example
|
||||
* // 默认嵌套执行,count=0 无限次
|
||||
* timer.run(callback, {delay: 2000});
|
||||
* // count=1 等同于 原始setTimeout
|
||||
* timer.run(callback, {delay: 2000, count:0});
|
||||
* 2. 支持 RAF 执行回调,用于小流渲染,audio音量获取等任务,需要渲染频率稳定,支持页面退后台后,用 setTimeout 接管,最短 1s 执行一次
|
||||
* @example
|
||||
* // 默认60fps,可以根据单位时长换算,默认开启后台执行
|
||||
* timer.run('raf', callback, {fps: 60});
|
||||
* // 设置执行次数
|
||||
* timer.run('raf', callback, {fps: 60, count: 300, backgroundTask: false});
|
||||
* 3. 支持空闲任务执行回调, requestIdleCallback 在帧渲染的空闲时间执行任务,可以用于 storage 写入等低优先级的任务
|
||||
* @example
|
||||
* // 支持原生setInterval 但不推荐使用,定时任务推荐用 timeout
|
||||
* timer.run('interval', callback, {delay:2000, count:10})
|
||||
*/
|
||||
class Timer {
|
||||
static generateTaskID() {
|
||||
return this.currentTaskID++;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {string} taskName 'interval' 'timeout'
|
||||
* @param {function} callback
|
||||
* @param {object} options include:
|
||||
* @param {number} options.delay millisecond
|
||||
* @param {number} options.count 定时器回调执行次数,0 无限次 or n次
|
||||
* @param {boolean} options.backgroundTask 在页面静默后是否继续执行定时器
|
||||
*/
|
||||
static run(taskName = index_1.NAME.TIMEOUT, callback, options) {
|
||||
// default options
|
||||
if (taskName === index_1.NAME.INTERVAL) {
|
||||
options = Object.assign({ delay: 2000, count: 0, backgroundTask: true }, options);
|
||||
}
|
||||
else {
|
||||
options = Object.assign({ delay: 2000, count: 0, backgroundTask: true }, options);
|
||||
}
|
||||
// call run(function, {...})
|
||||
if ((0, common_utils_1.isPlainObject)(callback)) {
|
||||
options = Object.assign(Object.assign({}, options), callback);
|
||||
}
|
||||
if ((0, common_utils_1.isFunction)(taskName)) {
|
||||
callback = taskName;
|
||||
taskName = index_1.NAME.TIMEOUT;
|
||||
}
|
||||
// 1. 创建 taskID,作为 timer task 的唯一标识,在本函数执行完后返回,用于在调用的地方实现互斥逻辑
|
||||
// 2. 根据 taskName 执行相应的函数
|
||||
const taskItem = Object.assign({ taskID: this.generateTaskID(), loopCount: 0, intervalID: null, timeoutID: null, taskName,
|
||||
callback }, options);
|
||||
this.taskMap.set(taskItem.taskID, taskItem);
|
||||
// console.log(`timer run task:${taskItem.taskName}, task queue size: ${this.taskMap.size}`);
|
||||
if (taskName === index_1.NAME.INTERNAL) {
|
||||
this.interval(taskItem);
|
||||
}
|
||||
else {
|
||||
this.timeout(taskItem);
|
||||
}
|
||||
return taskItem.taskID;
|
||||
}
|
||||
/**
|
||||
* 定时循环执行回调函数
|
||||
* 可以指定循环的时间间隔
|
||||
* 可以指定循环次数
|
||||
* @param {object} taskItem
|
||||
* @param {function} callback
|
||||
* @param {*} delay
|
||||
* @param {*} count
|
||||
* @returns ID
|
||||
*/
|
||||
static interval(taskItem) {
|
||||
// setInterval 缺点,浏览器退后台会降频,循环执行间隔时间不可靠
|
||||
// 创建进入定时器循环的任务函数,函数内:1. 判断是否满足执行条件,2.执行 callback
|
||||
// 通过 setInterval 执行任务函数
|
||||
// 将 intervalID 记录到 taskMap 对应的 item
|
||||
const task = () => {
|
||||
taskItem.callback();
|
||||
taskItem.loopCount += 1;
|
||||
if (this.isBreakLoop(taskItem)) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
return taskItem.intervalID = setInterval(task, taskItem.delay);
|
||||
}
|
||||
/**
|
||||
* 延迟执行回调
|
||||
* count = 0,循环
|
||||
* count = n, 执行n次
|
||||
* @param {object} taskItem
|
||||
*
|
||||
*/
|
||||
static timeout(taskItem) {
|
||||
// setTimeout 浏览器退后台,延迟变为至少1s
|
||||
const task = () => {
|
||||
// 执行回调
|
||||
taskItem.callback();
|
||||
taskItem.loopCount += 1;
|
||||
if (this.isBreakLoop(taskItem)) {
|
||||
return;
|
||||
}
|
||||
// 不修正延迟,每次callback间隔平均
|
||||
return taskItem.timeoutID = setTimeout(task, taskItem.delay);
|
||||
};
|
||||
return taskItem.timeoutID = setTimeout(task, taskItem.delay);
|
||||
}
|
||||
static hasTask(taskID) {
|
||||
return this.taskMap.has(taskID);
|
||||
}
|
||||
static clearTask(taskID) {
|
||||
// console.log('timer clearTask start', `| taskID:${taskID} | size:${this.taskMap.size}`);
|
||||
if (!this.taskMap.has(taskID)) {
|
||||
return true;
|
||||
}
|
||||
const { intervalID, timeoutID, onVisibilitychange } = this.taskMap.get(taskID);
|
||||
if (intervalID) {
|
||||
clearInterval(intervalID);
|
||||
}
|
||||
if (timeoutID) {
|
||||
clearTimeout(timeoutID);
|
||||
}
|
||||
if (onVisibilitychange) {
|
||||
document.removeEventListener('visibilitychange', onVisibilitychange);
|
||||
}
|
||||
this.taskMap.delete(taskID);
|
||||
// console.log('timer clearTask end ', `| size:${this.taskMap.size}`);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* 1. 如果已移除出定时队列,退出当前任务
|
||||
* 2. 如果当前任务已满足次数限制,则退出当前任务
|
||||
* @param {object} taskItem
|
||||
* @returns
|
||||
*/
|
||||
static isBreakLoop(taskItem) {
|
||||
if (!this.taskMap.has(taskItem.taskID)) {
|
||||
return true;
|
||||
}
|
||||
if (taskItem.count !== 0 && taskItem.loopCount >= taskItem.count) {
|
||||
this.clearTask(taskItem.taskID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Timer.taskMap = new Map();
|
||||
Timer.currentTaskID = 1;
|
||||
exports.default = Timer;
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* 装饰器:阻止函数重复调用
|
||||
* @export
|
||||
* @param {Object} options 入参
|
||||
* @param {Function} options.fn 函数
|
||||
* @param {Object} options.context 上下文对象
|
||||
* @param {String} options.name 函数名
|
||||
* @returns {Function} 封装后的函数
|
||||
*/
|
||||
export declare function avoidRepeatedCall(): (target: any, name: string, descriptor: any) => any;
|
||||
@@ -0,0 +1,49 @@
|
||||
"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.avoidRepeatedCall = void 0;
|
||||
const index_1 = require("../../const/index");
|
||||
/**
|
||||
* 装饰器:阻止函数重复调用
|
||||
* @export
|
||||
* @param {Object} options 入参
|
||||
* @param {Function} options.fn 函数
|
||||
* @param {Object} options.context 上下文对象
|
||||
* @param {String} options.name 函数名
|
||||
* @returns {Function} 封装后的函数
|
||||
*/
|
||||
function avoidRepeatedCall() {
|
||||
return function (target, name, descriptor) {
|
||||
const oldFn = descriptor.value;
|
||||
const isCallingSet = new Set();
|
||||
descriptor.value = function (...args) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (isCallingSet.has(this)) {
|
||||
console.warn((`${index_1.NAME.PREFIX}previous ${name}() is ongoing, please avoid repeated calls`));
|
||||
// throw new Error(`previous ${name}() is ongoing, please avoid repeated calls`);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
isCallingSet.add(this);
|
||||
const result = yield oldFn.apply(this, args);
|
||||
isCallingSet.delete(this);
|
||||
return result;
|
||||
}
|
||||
catch (error) {
|
||||
isCallingSet.delete(this);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
};
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
exports.avoidRepeatedCall = avoidRepeatedCall;
|
||||
@@ -0,0 +1,4 @@
|
||||
import { avoidRepeatedCall } from './avoidRepeatedCall';
|
||||
import { paramValidate } from './validateParams';
|
||||
import { VALIDATE_PARAMS } from './validateConfig';
|
||||
export { VALIDATE_PARAMS, paramValidate, avoidRepeatedCall, };
|
||||
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.avoidRepeatedCall = exports.paramValidate = exports.VALIDATE_PARAMS = void 0;
|
||||
const avoidRepeatedCall_1 = require("./avoidRepeatedCall");
|
||||
Object.defineProperty(exports, "avoidRepeatedCall", { enumerable: true, get: function () { return avoidRepeatedCall_1.avoidRepeatedCall; } });
|
||||
const validateParams_1 = require("./validateParams");
|
||||
Object.defineProperty(exports, "paramValidate", { enumerable: true, get: function () { return validateParams_1.paramValidate; } });
|
||||
const validateConfig_1 = require("./validateConfig");
|
||||
Object.defineProperty(exports, "VALIDATE_PARAMS", { enumerable: true, get: function () { return validateConfig_1.VALIDATE_PARAMS; } });
|
||||
@@ -0,0 +1,173 @@
|
||||
import { VideoResolution, VideoDisplayMode } from "../../const/index";
|
||||
export declare const VALIDATE_PARAMS: {
|
||||
init: {
|
||||
SDKAppID: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
userID: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
userSig: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
tim: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
};
|
||||
};
|
||||
call: {
|
||||
userID: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
type: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
range: number[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
roomID: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
range: string;
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
userData: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
timeout: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
};
|
||||
groupCall: {
|
||||
userIDList: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
type: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
range: number[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
groupID: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
roomID: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
range: string;
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
timeout: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
userData: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
offlinePushInfo: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
};
|
||||
joinInGroupCall: {
|
||||
type: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
range: number[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
groupID: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
roomID: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
};
|
||||
inviteUser: {
|
||||
userIDList: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
};
|
||||
setSelfInfo: {
|
||||
nickName: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
avatar: {
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
};
|
||||
};
|
||||
enableFloatWindow: {
|
||||
key: string;
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
}[];
|
||||
enableAIVoice: {
|
||||
key: string;
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
}[];
|
||||
enableMuteMode: {
|
||||
key: string;
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
}[];
|
||||
setCallingBell: {
|
||||
key: string;
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
}[];
|
||||
setLanguage: {
|
||||
key: string;
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
allowEmpty: boolean;
|
||||
}[];
|
||||
setVideoDisplayMode: {
|
||||
key: string;
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
range: VideoDisplayMode[];
|
||||
allowEmpty: boolean;
|
||||
}[];
|
||||
setVideoResolution: {
|
||||
key: string;
|
||||
required: boolean;
|
||||
rules: any[];
|
||||
range: VideoResolution[];
|
||||
allowEmpty: boolean;
|
||||
}[];
|
||||
};
|
||||
@@ -0,0 +1,190 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.VALIDATE_PARAMS = void 0;
|
||||
const index_1 = require("../../const/index");
|
||||
exports.VALIDATE_PARAMS = {
|
||||
init: {
|
||||
SDKAppID: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
allowEmpty: false,
|
||||
},
|
||||
userID: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false,
|
||||
},
|
||||
userSig: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false,
|
||||
},
|
||||
tim: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.OBJECT],
|
||||
},
|
||||
},
|
||||
call: {
|
||||
userID: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false
|
||||
},
|
||||
type: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
range: [1, 2],
|
||||
allowEmpty: false
|
||||
},
|
||||
roomID: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
range: `1~${index_1.MAX_NUMBER_ROOM_ID}`,
|
||||
allowEmpty: false,
|
||||
},
|
||||
userData: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false,
|
||||
},
|
||||
timeout: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
allowEmpty: false
|
||||
}
|
||||
},
|
||||
groupCall: {
|
||||
userIDList: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.ARRAY],
|
||||
allowEmpty: false
|
||||
},
|
||||
type: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
range: [1, 2],
|
||||
allowEmpty: false
|
||||
},
|
||||
groupID: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false
|
||||
},
|
||||
roomID: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
range: `1~${index_1.MAX_NUMBER_ROOM_ID}`,
|
||||
allowEmpty: false
|
||||
},
|
||||
timeout: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
allowEmpty: false
|
||||
},
|
||||
userData: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false,
|
||||
},
|
||||
offlinePushInfo: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.OBJECT],
|
||||
allowEmpty: false,
|
||||
},
|
||||
},
|
||||
joinInGroupCall: {
|
||||
type: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
range: [1, 2],
|
||||
allowEmpty: false
|
||||
},
|
||||
groupID: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false
|
||||
},
|
||||
roomID: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.NUMBER],
|
||||
allowEmpty: false,
|
||||
},
|
||||
},
|
||||
inviteUser: {
|
||||
userIDList: {
|
||||
required: true,
|
||||
rules: [index_1.NAME.ARRAY],
|
||||
allowEmpty: false
|
||||
},
|
||||
},
|
||||
setSelfInfo: {
|
||||
nickName: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false,
|
||||
},
|
||||
avatar: {
|
||||
required: false,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false,
|
||||
}
|
||||
},
|
||||
enableFloatWindow: [
|
||||
{
|
||||
key: "enable",
|
||||
required: false,
|
||||
rules: [index_1.NAME.BOOLEAN],
|
||||
allowEmpty: false,
|
||||
}
|
||||
],
|
||||
enableAIVoice: [
|
||||
{
|
||||
key: "enable",
|
||||
required: true,
|
||||
rules: [index_1.NAME.BOOLEAN],
|
||||
allowEmpty: false,
|
||||
}
|
||||
],
|
||||
enableMuteMode: [
|
||||
{
|
||||
key: "enable",
|
||||
required: true,
|
||||
rules: [index_1.NAME.BOOLEAN],
|
||||
allowEmpty: false,
|
||||
}
|
||||
],
|
||||
setCallingBell: [
|
||||
{
|
||||
key: "filePath",
|
||||
required: false,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: true,
|
||||
}
|
||||
],
|
||||
setLanguage: [
|
||||
{
|
||||
key: "language",
|
||||
required: true,
|
||||
rules: [index_1.NAME.STRING],
|
||||
allowEmpty: false
|
||||
}
|
||||
],
|
||||
setVideoDisplayMode: [
|
||||
{
|
||||
key: "displayMode",
|
||||
required: true,
|
||||
rules: [index_1.NAME.STRING],
|
||||
range: [index_1.VideoDisplayMode.CONTAIN, index_1.VideoDisplayMode.COVER, index_1.VideoDisplayMode.FILL],
|
||||
allowEmpty: false
|
||||
}
|
||||
],
|
||||
setVideoResolution: [
|
||||
{
|
||||
key: "resolution",
|
||||
required: true,
|
||||
rules: [index_1.NAME.STRING],
|
||||
range: [index_1.VideoResolution.RESOLUTION_1080P, index_1.VideoResolution.RESOLUTION_480P, index_1.VideoResolution.RESOLUTION_720P],
|
||||
allowEmpty: false
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export declare function paramValidate(config: any): (target: any, propertyName: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
||||
@@ -0,0 +1,86 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.paramValidate = void 0;
|
||||
const common_utils_1 = require("../common-utils");
|
||||
const index_1 = require("../../const/index");
|
||||
const PREFIX = index_1.NAME.PREFIX + "API";
|
||||
function paramValidate(config) {
|
||||
return function (target, propertyName, descriptor) {
|
||||
let method = descriptor.value;
|
||||
descriptor.value = function (...args) {
|
||||
doValidate.call(this, config, args, propertyName);
|
||||
return method.apply(this, args);
|
||||
};
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
exports.paramValidate = paramValidate;
|
||||
function doValidate(config, args, name) {
|
||||
try {
|
||||
// 兼容 init 方法中: SDKAppID sdkAppID 两种写法的参数校验判断
|
||||
if (!args[0].SDKAppID) {
|
||||
config = (0, common_utils_1.modifyObjectKey)(config, "SDKAppID", "sdkAppID");
|
||||
}
|
||||
if ((0, common_utils_1.isArray)(config)) {
|
||||
for (let i = 0; i < config.length; i++) {
|
||||
check.call(this, Object.assign(Object.assign({}, config[i]), { value: args[i], name }));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const key in config) {
|
||||
if (config.hasOwnProperty(key)) {
|
||||
check.call(this, Object.assign(Object.assign({}, config[key]), { value: args[0][key], name,
|
||||
key }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
function check({ required, rules, range, value, allowEmpty, name, key }) {
|
||||
// 用户没传指定参数
|
||||
if ((0, common_utils_1.isUndefined)(value)) {
|
||||
// 检查必填参数, 若配置是必填则报错
|
||||
if (required) {
|
||||
throw new Error(`${PREFIX}<${name}>: ${key} is required.`);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 判断参数类型是否正确
|
||||
const result = rules.some((item) => item === (0, common_utils_1.getType)(value));
|
||||
let type = '';
|
||||
if (!result) {
|
||||
for (let i = 0; i < rules.length; i++) {
|
||||
let str = rules[i];
|
||||
str = str.replace(str[0], str[0].toUpperCase());
|
||||
type += `${str}/`;
|
||||
}
|
||||
type = type.substring(0, type.length - 1);
|
||||
throw new Error(`${PREFIX}<${name}>: ${key} must be ${type}, current ${key} is ${typeof value}.`);
|
||||
}
|
||||
// 不允许传空值, 例如: '', ' '
|
||||
if (allowEmpty === false) {
|
||||
const isEmptyString = (0, common_utils_1.isString)(value) && value.trim() === '';
|
||||
if (isEmptyString) {
|
||||
throw new Error(`${PREFIX}<${name}>: ${key} is blank.`);
|
||||
}
|
||||
}
|
||||
// 判断是否符合限制条件
|
||||
if ((0, common_utils_1.isArray)(range)) {
|
||||
if (range && range.indexOf(value) === -1) {
|
||||
throw new Error(`${PREFIX}<${name}>: ${key} error, only be ${range}, current ${key} is ${value}.`);
|
||||
}
|
||||
}
|
||||
// 取值范围, 前闭后闭
|
||||
if ((0, common_utils_1.isString)(range) && range.indexOf('~') !== -1) {
|
||||
const valueList = range.split('~');
|
||||
if (value < +valueList[0] || value > +valueList[1] || ((0, common_utils_1.isNumber)(value) && Number.isNaN(value))) {
|
||||
throw new Error(`${PREFIX}<${name}>: ${key} error, only be ${range}, current ${key} is ${value}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user