Compare commits
13 Commits
53f100cb4e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| bc6643a6c2 | |||
| ec6b72042e | |||
| 207e242696 | |||
| d74ddf4ba2 | |||
| 31879a511d | |||
| 5240b57c47 | |||
| 7cf87a75fe | |||
| 05e354f148 | |||
| e20d2ea351 | |||
| c9d209d673 | |||
| 381dc73163 | |||
| 9e518a244a | |||
| a5b51b3492 |
5
.gitignore
vendored
5
.gitignore
vendored
@ -26,3 +26,8 @@ dist-ssr
|
|||||||
/.eslintrc-auto-import.json
|
/.eslintrc-auto-import.json
|
||||||
/components.d.ts
|
/components.d.ts
|
||||||
/examples/auto-imports.d.ts
|
/examples/auto-imports.d.ts
|
||||||
|
|
||||||
|
/CLAUDE.md
|
||||||
|
/AGENTS.md
|
||||||
|
/.claude
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
],
|
],
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
|
"types": "./dist/src/index.d.ts",
|
||||||
"import": "./dist/timi-web.mjs",
|
"import": "./dist/timi-web.mjs",
|
||||||
"require": "./dist/timi-web.umd.js"
|
"require": "./dist/timi-web.umd.js"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -30,8 +30,8 @@ body {
|
|||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow-x: hidden !important;
|
overflow-x: hidden;
|
||||||
overflow-y: scroll !important;
|
overflow-y: auto;
|
||||||
font-family: var(--tui-font);
|
font-family: var(--tui-font);
|
||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tui-copyright">
|
<div class="tui-copyright">
|
||||||
<p>朝朝频顾惜,夜夜不相忘</p>
|
<p v-text="text"></p>
|
||||||
<p v-if="icp" class="selectable">
|
<p v-if="icp" class="selectable">
|
||||||
<a href="https://beian.miit.gov.cn/" v-text="icp" :title="icp" target="_blank"></a>
|
<a href="https://beian.miit.gov.cn/" v-text="icp" :title="icp" target="_blank"></a>
|
||||||
</p>
|
</p>
|
||||||
@ -20,7 +20,9 @@ withDefaults(defineProps<{
|
|||||||
icp?: string;
|
icp?: string;
|
||||||
domain?: string;
|
domain?: string;
|
||||||
author?: string;
|
author?: string;
|
||||||
|
text?: string;
|
||||||
}>(), {
|
}>(), {
|
||||||
|
text: "朝朝频顾惜,夜夜不相忘"
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -56,7 +56,9 @@ const install = function (app: App) {
|
|||||||
app.use(component as unknown as { install: () => any });
|
app.use(component as unknown as { install: () => any });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const axios = Network.axios;
|
const axios = Network.axios;
|
||||||
|
const setGlobalErrorCallback = Network.setGlobalErrorCallback;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install
|
install
|
||||||
@ -65,6 +67,7 @@ export default {
|
|||||||
export {
|
export {
|
||||||
axios,
|
axios,
|
||||||
Network,
|
Network,
|
||||||
|
setGlobalErrorCallback,
|
||||||
|
|
||||||
UserAPI,
|
UserAPI,
|
||||||
CommonAPI,
|
CommonAPI,
|
||||||
|
|||||||
@ -53,7 +53,7 @@ export type CommentReplyView = {
|
|||||||
export type CommentPage = {
|
export type CommentPage = {
|
||||||
bizType?: CommentBizType;
|
bizType?: CommentBizType;
|
||||||
bizId?: number;
|
bizId?: number;
|
||||||
} & Page;
|
} & Page<Comment>;
|
||||||
|
|
||||||
export enum CommentReplyBizType {
|
export enum CommentReplyBizType {
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ export enum CommentReplyBizType {
|
|||||||
export type CommentReplyPage = {
|
export type CommentReplyPage = {
|
||||||
bizType: CommentReplyBizType
|
bizType: CommentReplyBizType
|
||||||
bizId?: number
|
bizId?: number
|
||||||
} & Page;
|
} & Page<Comment>;
|
||||||
|
|
||||||
export enum CommentBizType {
|
export enum CommentBizType {
|
||||||
ARTICLE = "ARTICLE",
|
ARTICLE = "ARTICLE",
|
||||||
|
|||||||
@ -13,17 +13,18 @@ export type Model = {
|
|||||||
deletedAt?: number;
|
deletedAt?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Response = {
|
export type Response<T> = {
|
||||||
code: number;
|
code: number;
|
||||||
msg?: string;
|
msg?: string;
|
||||||
data: object;
|
data: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Page = {
|
export type Page<T> = {
|
||||||
index: number;
|
index: number;
|
||||||
size: number;
|
size: number;
|
||||||
keyword?: string;
|
|
||||||
orderMap?: { [key: string]: OrderType };
|
orderMap?: { [key: string]: OrderType };
|
||||||
|
equalsExample?: T;
|
||||||
|
likesExample?: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum OrderType {
|
export enum OrderType {
|
||||||
@ -68,12 +69,12 @@ export enum ImageType {
|
|||||||
PIXELATED = "ir-pixelated"
|
PIXELATED = "ir-pixelated"
|
||||||
}
|
}
|
||||||
|
|
||||||
export type KeyValue<T> = {
|
export type KeyValue<V, K = string> = {
|
||||||
key: string;
|
key: K;
|
||||||
value: T;
|
value: V;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LabelValue<T> = {
|
export type LabelValue<L, V = string> = {
|
||||||
label: string;
|
label: L;
|
||||||
value: T;
|
value: V;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,4 +77,96 @@ export default class IOSize {
|
|||||||
}
|
}
|
||||||
return "0 B";
|
return "0 B";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将格式化的储存量字符串解析为字节量
|
||||||
|
* <p>支持格式:10GB, 10 GB, 1TB, 1.24 KB 等(单位不区分大小写)</p>
|
||||||
|
* <pre>
|
||||||
|
* // 返回 102400
|
||||||
|
* IOSize.parse("100 KB");
|
||||||
|
* // 返回 1073741824
|
||||||
|
* IOSize.parse("1GB");
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param sizeStr 格式化后的储存量字符串
|
||||||
|
* @return 字节量
|
||||||
|
* @throws Error 格式无效
|
||||||
|
*/
|
||||||
|
public static parse(sizeStr: string): number {
|
||||||
|
if (!sizeStr || sizeStr.trim() === "") {
|
||||||
|
throw new Error("not found sizeStr");
|
||||||
|
}
|
||||||
|
// 正则匹配:可选符号 + 数字(含小数点)+ 可选空格 + 单位
|
||||||
|
const pattern = /([-+]?\d+(?:\.\d+)?)\s*([a-zA-Z]+)/;
|
||||||
|
const matcher = pattern.exec(sizeStr.trim());
|
||||||
|
if (matcher) {
|
||||||
|
let value: number;
|
||||||
|
try {
|
||||||
|
value = parseFloat(matcher[1]);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error("invalid number format: " + matcher[1]);
|
||||||
|
}
|
||||||
|
if (value < 0) {
|
||||||
|
throw new Error("size cannot be negative: " + value);
|
||||||
|
}
|
||||||
|
const unitStr = matcher[2].toUpperCase();
|
||||||
|
let unit: Unit;
|
||||||
|
|
||||||
|
// 先尝试精确匹配枚举
|
||||||
|
if (Object.values(Unit).includes(unitStr as Unit)) {
|
||||||
|
unit = unitStr as Unit;
|
||||||
|
} else {
|
||||||
|
// 处理单字母单位缩写(K/M/G/T/P/E)
|
||||||
|
switch (unitStr.charAt(0)) {
|
||||||
|
case "K":
|
||||||
|
unit = Unit.KB;
|
||||||
|
break;
|
||||||
|
case "M":
|
||||||
|
unit = Unit.MB;
|
||||||
|
break;
|
||||||
|
case "G":
|
||||||
|
unit = Unit.GB;
|
||||||
|
break;
|
||||||
|
case "T":
|
||||||
|
unit = Unit.TB;
|
||||||
|
break;
|
||||||
|
case "P":
|
||||||
|
unit = Unit.PB;
|
||||||
|
break;
|
||||||
|
case "E":
|
||||||
|
unit = Unit.EB;
|
||||||
|
break;
|
||||||
|
case "B":
|
||||||
|
unit = Unit.B;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error("Unknown unit: " + unitStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IOSize.toBytes(value, unit);
|
||||||
|
}
|
||||||
|
// 尝试解析纯数字(无单位,默认字节)
|
||||||
|
try {
|
||||||
|
const bytes = parseInt(sizeStr.trim());
|
||||||
|
if (bytes < 0) {
|
||||||
|
throw new Error("size cannot be negative: " + bytes);
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error("invalid size format: " + sizeStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换值到字节量
|
||||||
|
*
|
||||||
|
* @param value 值
|
||||||
|
* @param unit 单位
|
||||||
|
* @return 字节量
|
||||||
|
*/
|
||||||
|
private static toBytes(value: number, unit: Unit): number {
|
||||||
|
const units = Object.values(Unit);
|
||||||
|
const ordinal = units.indexOf(unit);
|
||||||
|
return Math.round(value * Math.pow(1024, ordinal));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,14 @@ import axios, { InternalAxiosRequestConfig } from "axios";
|
|||||||
import { Response } from "~/types/Model";
|
import { Response } from "~/types/Model";
|
||||||
import { Cooker, Time, userStore } from "~/index";
|
import { Cooker, Time, userStore } from "~/index";
|
||||||
|
|
||||||
|
type ErrorCallback = (response: Response<any>) => void;
|
||||||
|
|
||||||
|
let globalErrorCallback: ErrorCallback | null = null;
|
||||||
|
|
||||||
|
export const setGlobalErrorCallback = (callback: ErrorCallback) => {
|
||||||
|
globalErrorCallback = callback;
|
||||||
|
};
|
||||||
|
|
||||||
const userTokenInterceptors = async (config: InternalAxiosRequestConfig<any>) => {
|
const userTokenInterceptors = async (config: InternalAxiosRequestConfig<any>) => {
|
||||||
let token = userStore.loginUser.token?.value;
|
let token = userStore.loginUser.token?.value;
|
||||||
const cookieToken = Cooker.get("Token");
|
const cookieToken = Cooker.get("Token");
|
||||||
@ -25,19 +33,22 @@ const userTokenInterceptors = async (config: InternalAxiosRequestConfig<any>) =>
|
|||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
axios.defaults.withCredentials = true;
|
axios.defaults.withCredentials = true;
|
||||||
axios.interceptors.response.use((response: any) => {
|
axios.interceptors.response.use((axiosResp: any) => {
|
||||||
if (!response.config.responseType) {
|
if (!axiosResp.config.responseType) {
|
||||||
// 服务端返回
|
// 服务端返回
|
||||||
const data = response.data as Response;
|
const serverResp = axiosResp.data as Response<any>;
|
||||||
if (data.code < 40000) {
|
if (serverResp.code < 40000) {
|
||||||
// 200 或 300 HTTP 状态段视为成功
|
// 200 或 300 HTTP 状态段视为成功
|
||||||
return data.data;
|
return serverResp.data;
|
||||||
} else {
|
} else {
|
||||||
|
if (globalErrorCallback) {
|
||||||
|
globalErrorCallback(serverResp);
|
||||||
|
}
|
||||||
// 由调用方处理
|
// 由调用方处理
|
||||||
return Promise.reject(data.msg);
|
return Promise.reject(serverResp.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return response.data;
|
return axiosResp.data;
|
||||||
}, (error: any) => {
|
}, (error: any) => {
|
||||||
// 请求错误
|
// 请求错误
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -57,5 +68,6 @@ axios.interceptors.response.use((response: any) => {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
axios,
|
axios,
|
||||||
userTokenInterceptors
|
userTokenInterceptors,
|
||||||
|
setGlobalErrorCallback
|
||||||
};
|
};
|
||||||
|
|||||||
@ -50,8 +50,8 @@ export default class Prismjs {
|
|||||||
this.map.set(PrismjsType.Initialization, {extensions: ["ini"], prismjs: "ini", viewer: PrismjsViewer.CODE});
|
this.map.set(PrismjsType.Initialization, {extensions: ["ini"], prismjs: "ini", viewer: PrismjsViewer.CODE});
|
||||||
this.map.set(PrismjsType.PHP, {extensions: ["php"], prismjs: "php", viewer: PrismjsViewer.CODE});
|
this.map.set(PrismjsType.PHP, {extensions: ["php"], prismjs: "php", viewer: PrismjsViewer.CODE});
|
||||||
this.map.set(PrismjsType.SQL, {extensions: ["sql"], prismjs: "sql", viewer: PrismjsViewer.CODE});
|
this.map.set(PrismjsType.SQL, {extensions: ["sql"], prismjs: "sql", viewer: PrismjsViewer.CODE});
|
||||||
this.map.set(PrismjsType.XML, {extensions: ["xml", "fxml"], prismjs: "xml", viewer: PrismjsViewer.CODE});
|
this.map.set(PrismjsType.XML, {extensions: ["xml", "fxml", "wxml"], prismjs: "xml", viewer: PrismjsViewer.CODE});
|
||||||
this.map.set(PrismjsType.CSS, {extensions: ["css"], prismjs: "css", viewer: PrismjsViewer.CODE});
|
this.map.set(PrismjsType.CSS, {extensions: ["css", "wxss"], prismjs: "css", viewer: PrismjsViewer.CODE});
|
||||||
this.map.set(PrismjsType.LESS, {extensions: ["less"], prismjs: "less", viewer: PrismjsViewer.CODE});
|
this.map.set(PrismjsType.LESS, {extensions: ["less"], prismjs: "less", viewer: PrismjsViewer.CODE});
|
||||||
this.map.set(PrismjsType.Markup, {extensions: ["htm", "html"], prismjs: "markup", viewer: PrismjsViewer.CODE});
|
this.map.set(PrismjsType.Markup, {extensions: ["htm", "html"], prismjs: "markup", viewer: PrismjsViewer.CODE});
|
||||||
this.map.set(PrismjsType.YAML, {extensions: ["yml", "yaml"], prismjs: "yaml", viewer: PrismjsViewer.CODE});
|
this.map.set(PrismjsType.YAML, {extensions: ["yml", "yaml"], prismjs: "yaml", viewer: PrismjsViewer.CODE});
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export default class SettingMapper {
|
|||||||
|
|
||||||
private map = new Map<string, Ref<string>>();
|
private map = new Map<string, Ref<string>>();
|
||||||
|
|
||||||
public static async loadSetting(...settings: { key: string, args?: { [key: string]: any }}[]): Promise<void> {
|
public static async loadSetting(...settings: (string | { key: string, args?: { [key: string]: any }})[]): Promise<void> {
|
||||||
const map = new Map<string, object | undefined>();
|
const map = new Map<string, object | undefined>();
|
||||||
{
|
{
|
||||||
// 默认配置
|
// 默认配置
|
||||||
@ -34,7 +34,12 @@ export default class SettingMapper {
|
|||||||
{
|
{
|
||||||
// 附加配置
|
// 附加配置
|
||||||
for (let i = 0; i < settings.length; i++) {
|
for (let i = 0; i < settings.length; i++) {
|
||||||
map.set(settings[i].key, settings[i].args);
|
const setting = settings[i];
|
||||||
|
if (typeof setting === 'string') {
|
||||||
|
map.set(setting, undefined);
|
||||||
|
} else {
|
||||||
|
map.set(setting.key, setting.args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const instance = this.getInstance();
|
const instance = this.getInstance();
|
||||||
|
|||||||
@ -69,6 +69,26 @@ export default class Time {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将毫秒值转换为可读的时间字符串
|
||||||
|
*
|
||||||
|
* @param ms 毫秒值
|
||||||
|
* @return 时间字符串,如 "10 天"、"5 小时"、"30 分钟"、"15 秒"、"500 毫秒"
|
||||||
|
*/
|
||||||
|
public static toString(ms: number): string {
|
||||||
|
if (Time.D <= ms) {
|
||||||
|
return `${Math.floor(ms / Time.D)} 天`;
|
||||||
|
} else if (Time.H <= ms) {
|
||||||
|
return `${Math.floor(ms / Time.H)} 小时`;
|
||||||
|
} else if (Time.M <= ms) {
|
||||||
|
return `${Math.floor(ms / Time.M)} 分钟`;
|
||||||
|
} else if (Time.S <= ms) {
|
||||||
|
return `${Math.floor(ms / Time.S)} 秒`;
|
||||||
|
} else {
|
||||||
|
return `${Math.floor(ms)} 毫秒`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static between(begin: Date, end?: Date) : any {
|
public static between(begin: Date, end?: Date) : any {
|
||||||
if (!end) {
|
if (!end) {
|
||||||
end = new Date();
|
end = new Date();
|
||||||
@ -94,4 +114,58 @@ export default class Time {
|
|||||||
}
|
}
|
||||||
return `${minutes.toString().padStart(2, "0")}:${second.toString().padStart(2, "0")}`;
|
return `${minutes.toString().padStart(2, "0")}:${second.toString().padStart(2, "0")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将时间字符串解析为毫秒值
|
||||||
|
*
|
||||||
|
* <p>支持的格式示例:
|
||||||
|
* <pre>
|
||||||
|
* 10 = 10
|
||||||
|
* 10ms = 10
|
||||||
|
* 10s = 10,000
|
||||||
|
* 10m = 600,000
|
||||||
|
* 10h = 36,000,000
|
||||||
|
* 10d = 10D = 10 d = 864,000,000
|
||||||
|
* 10.5d = 907,200,000
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param timeStr 时间字符串
|
||||||
|
* @return 毫秒
|
||||||
|
* @throws Error 输入格式无效
|
||||||
|
*/
|
||||||
|
public static parseToMS(timeStr: string): number {
|
||||||
|
if (!timeStr || timeStr.trim() === "") {
|
||||||
|
throw new Error("not found timeStr");
|
||||||
|
}
|
||||||
|
const normalized = timeStr.replace(/\s+/g, "").toLowerCase();
|
||||||
|
|
||||||
|
const pattern = /^(\d+(?:\.\d+)?)(ms|[dhms])?$/;
|
||||||
|
const matcher = pattern.exec(normalized);
|
||||||
|
if (!matcher) {
|
||||||
|
throw new Error("invalid format: " + timeStr);
|
||||||
|
}
|
||||||
|
const value = parseFloat(matcher[1]);
|
||||||
|
const unit = matcher[2];
|
||||||
|
if (!unit || unit === "ms") {
|
||||||
|
return Math.round(value);
|
||||||
|
}
|
||||||
|
let multiplier: number;
|
||||||
|
switch (unit) {
|
||||||
|
case "s":
|
||||||
|
multiplier = Time.S;
|
||||||
|
break;
|
||||||
|
case "m":
|
||||||
|
multiplier = Time.M;
|
||||||
|
break;
|
||||||
|
case "h":
|
||||||
|
multiplier = Time.H;
|
||||||
|
break;
|
||||||
|
case "d":
|
||||||
|
multiplier = Time.D;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error("invalid format unit: " + unit);
|
||||||
|
}
|
||||||
|
return Math.round(value * multiplier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -144,7 +144,7 @@ export default class Toolkit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机数
|
* 生成随机数(整数)
|
||||||
*
|
*
|
||||||
* @param min 最小值
|
* @param min 最小值
|
||||||
* @param max 最大值
|
* @param max 最大值
|
||||||
@ -153,6 +153,16 @@ export default class Toolkit {
|
|||||||
return Math.floor(Math.random() * (max + 1 - min)) + min;
|
return Math.floor(Math.random() * (max + 1 - min)) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机数(浮点数)
|
||||||
|
*
|
||||||
|
* @param min 最小值
|
||||||
|
* @param max 最大值
|
||||||
|
*/
|
||||||
|
public static randomDouble(min = 0, max = 1): number {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base64 数据转文件
|
* Base64 数据转文件
|
||||||
*
|
*
|
||||||
@ -351,4 +361,66 @@ export default class Toolkit {
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static doNotNull(arg: any, func: (arg: any) => void): void {
|
||||||
|
if (arg) {
|
||||||
|
func(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static toCssSize(value: number | string): string {
|
||||||
|
if (typeof value === "number") {
|
||||||
|
return `${value}px`;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置随机间隔执行
|
||||||
|
*
|
||||||
|
* @param config 配置对象
|
||||||
|
* @param config.handler 处理函数,如果提供了 min 和 max,则会接收随机数作为参数
|
||||||
|
* @param config.handleRate 执行概率,0-1 之间,默认 1(总是执行)
|
||||||
|
* @param config.interval 间隔时间(毫秒)
|
||||||
|
* @param config.min 随机数最小值(可选),提供时会生成随机数传给 handler
|
||||||
|
* @param config.max 随机数最大值(可选),提供时会生成随机数传给 handler
|
||||||
|
* @returns 定时器 ID
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* // 简单的随机执行
|
||||||
|
* setRandomInterval({
|
||||||
|
* handler: () => console.log('executed'),
|
||||||
|
* handleRate: 0.5,
|
||||||
|
* interval: 1000
|
||||||
|
* })
|
||||||
|
*
|
||||||
|
* // 带随机数参数的执行
|
||||||
|
* setRandomInterval({
|
||||||
|
* handler: (value) => console.log('random value:', value),
|
||||||
|
* handleRate: 1,
|
||||||
|
* min: 0,
|
||||||
|
* max: 100,
|
||||||
|
* interval: 1000
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public static setRandomInterval(config: {
|
||||||
|
handler: Function | ((value: number) => void);
|
||||||
|
handleRate?: number;
|
||||||
|
interval?: number;
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
}): NodeJS.Timeout {
|
||||||
|
const { handler, handleRate = 1, interval, min, max } = config;
|
||||||
|
return setInterval(() => {
|
||||||
|
if (Math.random() < handleRate) {
|
||||||
|
if (min !== undefined && max !== undefined) {
|
||||||
|
(handler as (value: number) => void)(this.randomDouble(min, max));
|
||||||
|
} else {
|
||||||
|
(handler as Function)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, interval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user