/* * @Author: your name * @Date: 2022-01-13 17:09:05 * @LastEditTime: 2025-04-17 11:01:43 * @LastEditors: code4eat awesomedema@gmail.com * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @FilePath: /KC-MiddlePlatform/src/utils.js */ import axios, { AxiosResponse } from 'axios'; import { Key } from 'react'; /** * 生成指定长度的随机字符串 * @param length 字符串长度 * @returns 随机字符串 */ export const randomString = (length: number): string => { const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_=-'; return Array.from( { length }, () => chars[Math.floor(Math.random() * chars.length)] ).join(''); }; export interface TreeItemType { children?: TreeItemType[]; [key: string]: any; } /** * 从树结构中获取指定键的所有值 * @param data 树结构数据 * @param key 要获取的键名 * @returns 值的数组 */ export const getValsFromTree = (data: TreeItemType[], key: string): any[] => { const result: any[] = []; const traverse = (nodes: TreeItemType[]): void => { nodes.forEach((node) => { if (node[key]) { result.push(node[key]); } if (node.children?.length) { traverse(node.children); } }); }; traverse(data); return result; }; export const searchTree = (treeData: TreeItemType[]) => {}; /** * 下载模板文件 * @param path 文件路径 */ export const downloadTemplateReq = async (path: string): Promise => { try { const userData = localStorage.getItem('userData'); const { token = '' } = JSON.parse(userData || '{}'); const response: AxiosResponse = await axios({ method: 'get', url: `/gateway/${path}`, responseType: 'blob', headers: { token }, }); const filename = decodeURI(response.headers['content-disposition']); const blob = new Blob([response.data], { type: 'application/vnd.ms-excel', }); const objectUrl = URL.createObjectURL(blob); const link = document.createElement('a'); link.download = `${filename}.xls`; link.href = objectUrl; link.style.display = 'none'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(objectUrl); } catch (error) { console.error('下载模板失败:', error); throw error; } }; /** * 获取树结构中最深的节点及其父节点 * @param tree 树结构 * @param childrenName 子节点属性名 * @returns [最深节点, 父节点] */ export const getDeepestTreeData = ( tree: T, childrenName: string ): [T, T | undefined] => { let parent: T | undefined; const traverse = (node: T): T => { if (node[childrenName]?.length) { parent = node; return traverse(node[childrenName][0]); } return node; }; return [traverse(tree), parent]; }; /** * 数组去重 * @param arr 数组 * @param uniId 唯一标识字段 * @returns 去重后的数组 */ export const uniqueFunc = (arr: T[], uniId: string): T[] => { const uniqueMap = new Map(); return arr.filter((item) => !uniqueMap.has(item[uniId]) && uniqueMap.set(item[uniId], 1)); }; //获取树结构的所有叶子节点 interface TreeNode { [key: string]: any; child?: TreeNode[]; } /** * 获取树的所有叶子节点 * @param node 树节点 * @param leaves 叶子节点数组 * @returns 叶子节点数组 */ export const getLeafNodes = (node: TreeNode, leaves: TreeNode[] = []): TreeNode[] => { if (!node.child?.length) { leaves.push(node); } else { node.child.forEach((child) => getLeafNodes(child, leaves)); } return leaves; }; //根据树结构中的某个属性的集合,获取对应的节点,返回一个集合 /** * 根据属性值查找节点 * @param node 树节点 * @param keys 属性值集合 * @param str 属性名 * @returns 匹配的节点数组 */ export const findNodesBySomes = ( node: TreeNode, keys: Set, str: string ): TreeNode[] => { const results: TreeNode[] = []; if (keys.has(node[str])) { results.push(node); } if (node.child?.length) { node.child.forEach((child) => { results.push(...findNodesBySomes(child, keys, str)); }); } return results; }; //更改树结构集合的子集属性名 /** * 重命名子节点属性 * @param nodes 节点数组 * @param key 要重命名的属性名 * @returns 处理后的节点数组 */ export const renameChildListToChildren = ( nodes: T[], key: string ): T[] => { return nodes.map((node) => { const newNode = { ...node }; if (newNode[key]?.length) { newNode.children = renameChildListToChildren(newNode[key], key); } return newNode; }); }; //获取目标节点的所有父节点,且以集合的方式返回 /** * 查找节点的所有父节点 * @param tree 树结构 * @param targetNodeKeyName 目标节点键名 * @param targetNodeKeyVal 目标节点键值 * @param path 路径 * @returns 父节点数组或null */ export const findParents = ( tree: TreeNode[], targetNodeKeyName: string, targetNodeKeyVal: Key, path: TreeNode[] = [] ): TreeNode[] | null => { for (const node of tree) { if (node[targetNodeKeyName] === targetNodeKeyVal) { return [...path, node]; } if (node.children?.length) { const result = findParents(node.children, targetNodeKeyName, targetNodeKeyVal, [...path, node]); if (result) return result; } } return null; }; //搜索树结果 /** * 搜索树结构并保持结构 * @param nodes 节点数组 * @param keyName 键名 * @param keyVal 键值 * @returns 匹配的节点数组 */ export const searchTreeAndKeepStructure = ( nodes: T[], keyName: string, keyVal: any ): T[] => { return nodes.reduce((result, node) => { if (String(node[keyName]).includes(String(keyVal))) { result.push({ ...node, children: node.children?.length ? searchTreeAndKeepStructure(node.children, keyName, keyVal) : undefined, }); } else if (node.children?.length) { const children = searchTreeAndKeepStructure(node.children, keyName, keyVal); if (children.length) { result.push({ ...node, children }); } } return result; }, []); };