91 lines
2.0 KiB
TypeScript
91 lines
2.0 KiB
TypeScript
|
|
/**
|
||
|
|
* 通用工具函数
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 生成唯一 ID
|
||
|
|
*/
|
||
|
|
export function uniqueId(prefix = ''): string {
|
||
|
|
const id = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
|
||
|
|
return prefix ? `${prefix}_${id}` : id;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 简易深拷贝(基于 JSON,适用于纯数据对象)
|
||
|
|
*/
|
||
|
|
export function deepClone<T>(value: T): T {
|
||
|
|
return JSON.parse(JSON.stringify(value));
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 防抖
|
||
|
|
*/
|
||
|
|
export function debounce<T extends (...args: any[]) => any>(fn: T, wait = 300) {
|
||
|
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
||
|
|
const debounced = (...args: Parameters<T>) => {
|
||
|
|
if (timer) clearTimeout(timer);
|
||
|
|
timer = setTimeout(() => fn(...args), wait);
|
||
|
|
};
|
||
|
|
debounced.cancel = () => {
|
||
|
|
if (timer) clearTimeout(timer);
|
||
|
|
timer = null;
|
||
|
|
};
|
||
|
|
return debounced;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 节流
|
||
|
|
*/
|
||
|
|
export function throttle<T extends (...args: any[]) => any>(fn: T, wait = 300) {
|
||
|
|
let lastTime = 0;
|
||
|
|
return (...args: Parameters<T>) => {
|
||
|
|
const now = Date.now();
|
||
|
|
if (now - lastTime >= wait) {
|
||
|
|
lastTime = now;
|
||
|
|
fn(...args);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 格式化日期
|
||
|
|
*/
|
||
|
|
export function formatDate(date: Date | string | number, format = 'YYYY-MM-DD HH:mm:ss'): string {
|
||
|
|
const d = new Date(date);
|
||
|
|
if (Number.isNaN(d.getTime())) return '';
|
||
|
|
|
||
|
|
const pad = (n: number) => String(n).padStart(2, '0');
|
||
|
|
const map: Record<string, string> = {
|
||
|
|
YYYY: String(d.getFullYear()),
|
||
|
|
MM: pad(d.getMonth() + 1),
|
||
|
|
DD: pad(d.getDate()),
|
||
|
|
HH: pad(d.getHours()),
|
||
|
|
mm: pad(d.getMinutes()),
|
||
|
|
ss: pad(d.getSeconds()),
|
||
|
|
};
|
||
|
|
|
||
|
|
return format.replace(/YYYY|MM|DD|HH|mm|ss/g, (match) => map[match]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 树形数据扁平化
|
||
|
|
*/
|
||
|
|
export interface TreeNode {
|
||
|
|
id: string | number;
|
||
|
|
children?: TreeNode[];
|
||
|
|
[key: string]: any;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function flattenTree<T extends TreeNode>(tree: T[]): T[] {
|
||
|
|
const result: T[] = [];
|
||
|
|
const stack = [...tree].reverse();
|
||
|
|
while (stack.length) {
|
||
|
|
const node = stack.pop() as T;
|
||
|
|
result.push(node);
|
||
|
|
if (node.children?.length) {
|
||
|
|
stack.push(...(node.children as T[]).reverse());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|