index.ts 2.26 KB
/** 通用工具函数(不依赖任何 store,避免循环引用) */

/** 是否为外链 */
export function isExternal(path: string): boolean {
  return /^(https?:|mailto:|tel:)/.test(path)
}

/** kebab-case / snake_case → PascalCase(Icon 组件用) */
export function toPascalCase(str: string): string {
  return (str || '')
    .split(/[-_\s]+/)
    .filter(Boolean)
    .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
    .join('')
}

/** 去掉首尾斜杠 */
export function trimSlash(path: string): string {
  return (path || '').replace(/^\/+|\/+$/g, '')
}

/** 拼接路径,自动去重斜杠 */
export function joinPath(...parts: string[]): string {
  return (
    '/' +
    parts
      .map((p) => trimSlash(p))
      .filter(Boolean)
      .join('/')
  )
}

/** 把时间戳格式化为 yyyy-MM-dd HH:mm:ss */
export function formatDateTime(input?: number | string | Date, withTime = true): string {
  if (input === undefined || input === null || input === '') return '-'
  const d = input instanceof Date ? input : new Date(typeof input === 'number' ? input : String(input).replace(/-/g, '/'))
  if (isNaN(d.getTime())) return '-'
  const p = (n: number) => String(n).padStart(2, '0')
  const date = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`
  return withTime ? `${date} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}` : date
}

/** 列表 → 树(后端没直接给树时使用;parentId 为 null/0/undefined 视为根) */
export function buildTree<T extends Record<string, any>>(
  list: T[],
  idKey = 'id',
  parentKey = 'parentId',
  childrenKey = 'children'
): T[] {
  const map = new Map<any, T>()
  const roots: T[] = []
  ;(list || []).forEach((item) => map.set(item[idKey], { ...item, [childrenKey]: [] }))
  ;(list || []).forEach((item) => {
    const node = map.get(item[idKey])!
    const parent = map.get(item[parentKey])
    if (parent && parent !== node) {
      ;(parent[childrenKey] as T[]).push(node)
    } else {
      roots.push(node)
    }
  })
  return roots
}

/** 简易防抖 */
export function debounce<T extends (...args: any[]) => void>(fn: T, delay = 300) {
  let timer: any = null
  return (...args: Parameters<T>) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => fn(...args), delay)
  }
}