/** * 辅助工具函数 * 从原项目 src/utils/array.js, dom.js, html.js 迁移 */ /** * 规范化数组响应(处理后端可能返回非数组的情况) */ export function normalizeArrayResponse(data: T | T[] | null | undefined): T[] { if (!data) return []; if (Array.isArray(data)) return data; return [data]; } /** * 防抖函数 */ export function debounce any>( func: T, delay: number ): (...args: Parameters) => void { let timeoutId: ReturnType; return function (this: any, ...args: Parameters) { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; } /** * 节流函数 */ export function throttle any>( func: T, limit: number ): (...args: Parameters) => void { let inThrottle: boolean; return function (this: any, ...args: Parameters) { 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(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 { return new Promise((resolve) => setTimeout(resolve, ms)); }