import { $t } from '@/locales'; /** * Transform record to option * * @example * ```ts * const record = { * key1: 'label1', * key2: 'label2' * }; * const options = transformRecordToOption(record); * // [ * // { value: 'key1', label: 'label1' }, * // { value: 'key2', label: 'label2' } * // ] * ```; * * @param record */ export function transformRecordToOption>(record: T) { return Object.entries(record).map(([value, label]) => ({ value, label })) as CommonType.Option[]; } export function transformRecordToNumberOption>(record: T) { return Object.entries(record).map(([value, label]) => ({ value, label })) as CommonType.Option[]; } /** * Translate options * * @param options */ export function translateOptions(options: CommonType.Option[]) { return options.map(option => ({ ...option, label: $t(option.label as App.I18n.I18nKey) })); } /** * Toggle html class * * @param className */ export function toggleHtmlClass(className: string) { function add() { document.documentElement.classList.add(className); } function remove() { document.documentElement.classList.remove(className); } return { add, remove }; } /* 驼峰转换下划线 */ export function humpToLine(str: string, line: string = '-') { let temp = str.replace(/[A-Z]/g, match => { return `${line}${match.toLowerCase()}`; }); // 如果首字母是大写,执行replace时会多一个_,这里需要去掉 if (temp.slice(0, 1) === line) { temp = temp.slice(1); } return temp; } /** 判断是否为空 */ export function isNotNull(value: any) { return value !== undefined && value !== null && value !== '' && value !== 'undefined' && value !== 'null'; } /** 判断是否为空 */ export function isNull(value: any) { return value === undefined || value === null || value === '' || value === 'undefined' || value === 'null'; } /** 判断是否为图片类型 */ export function isImage(suffix: string) { const imgSuffixList = ['.jpg', '.jpeg', '.png', '.gif', '.webp']; return imgSuffixList.includes(suffix.toLowerCase()); } /** * 构造树型结构数据 * * @param {T[]} data 数据源 * @param {TreeConfig} config 配置选项 * @returns {T[]} 树形结构数据 */ export const handleTree = >(data: T[], config: CommonType.TreeConfig): T[] => { if (!data?.length) { return []; } const { idField, parentIdField = 'parentId', childrenField = 'children', filterFn = () => true // 添加过滤函数,默认为不过滤 } = config; // 使用 Map 替代普通对象,提高性能 const childrenMap = new Map(); const nodeMap = new Map(); const tree: T[] = []; // 第一遍遍历:构建节点映射 for (const item of data) { const id = item[idField]; const parentId = item[parentIdField]; nodeMap.set(id, item); if (!childrenMap.has(parentId)) { childrenMap.set(parentId, []); } // 应用过滤函数 if (filterFn(item)) { childrenMap.get(parentId)!.push(item); } } // 第二遍遍历:找出根节点 for (const item of data) { const parentId = item[parentIdField]; if (!nodeMap.has(parentId) && filterFn(item)) { tree.push(item); } } // 递归构建树形结构 const buildTree = (node: T) => { const id = node[idField]; const children = childrenMap.get(id); if (children?.length) { // 使用类型断言确保类型安全 (node as any)[childrenField] = children; for (const child of children) { buildTree(child); } } else { // 如果没有子节点,设置为 undefined (node as any)[childrenField] = undefined; } }; // 从根节点开始构建树 for (const root of tree) { buildTree(root); } return tree; };