mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-19 03:00:49 +08:00
feat: initialize new React application structure with TypeScript, ESLint, and Prettier configurations, while removing legacy files and adding new components and pages for enhanced functionality
This commit is contained in:
87
src/utils/helpers.ts
Normal file
87
src/utils/helpers.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* 辅助工具函数
|
||||
* 从原项目 src/utils/array.js, dom.js, html.js 迁移
|
||||
*/
|
||||
|
||||
/**
|
||||
* 规范化数组响应(处理后端可能返回非数组的情况)
|
||||
*/
|
||||
export function normalizeArrayResponse<T>(data: T | T[] | null | undefined): T[] {
|
||||
if (!data) return [];
|
||||
if (Array.isArray(data)) return data;
|
||||
return [data];
|
||||
}
|
||||
|
||||
/**
|
||||
* 防抖函数
|
||||
*/
|
||||
export function debounce<T extends (...args: any[]) => any>(
|
||||
func: T,
|
||||
delay: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let timeoutId: ReturnType<typeof setTimeout>;
|
||||
|
||||
return function (this: any, ...args: Parameters<T>) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => func.apply(this, args), delay);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 节流函数
|
||||
*/
|
||||
export function throttle<T extends (...args: any[]) => any>(
|
||||
func: T,
|
||||
limit: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let inThrottle: boolean;
|
||||
|
||||
return function (this: any, ...args: Parameters<T>) {
|
||||
if (!inThrottle) {
|
||||
func.apply(this, args);
|
||||
inThrottle = true;
|
||||
setTimeout(() => (inThrottle = false), limit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML 转义(防 XSS)
|
||||
*/
|
||||
export function escapeHtml(text: string): string {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成唯一 ID
|
||||
*/
|
||||
export function generateId(): string {
|
||||
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 深拷贝对象
|
||||
*/
|
||||
export function deepClone<T>(obj: T): T {
|
||||
if (obj === null || typeof obj !== 'object') return obj;
|
||||
|
||||
if (obj instanceof Date) return new Date(obj.getTime()) as any;
|
||||
if (obj instanceof Array) return obj.map((item) => deepClone(item)) as any;
|
||||
|
||||
const clonedObj = {} as T;
|
||||
for (const key in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
clonedObj[key] = deepClone((obj as any)[key]);
|
||||
}
|
||||
}
|
||||
return clonedObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟函数
|
||||
*/
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
Reference in New Issue
Block a user