ruoyi-plus-soybean/src/utils/common.ts
2025-04-24 22:23:08 +08:00

166 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<T extends Record<string, string>>(record: T) {
return Object.entries(record).map(([value, label]) => ({
value,
label
})) as CommonType.Option<keyof T>[];
}
export function transformRecordToNumberOption<T extends Record<string, string>>(record: T) {
return Object.entries(record).map(([value, label]) => ({
value,
label
})) as CommonType.Option<keyof T>[];
}
/**
* Translate options
*
* @param options
*/
export function translateOptions(options: CommonType.Option<string>[]) {
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 = <T extends Record<string, any>>(data: T[], config: CommonType.TreeConfig): T[] => {
if (!data?.length) {
return [];
}
const {
idField,
parentIdField = 'parentId',
childrenField = 'children',
filterFn = () => true // 添加过滤函数,默认为不过滤
} = config;
// 使用 Map 替代普通对象,提高性能
const childrenMap = new Map<string | number, T[]>();
const nodeMap = new Map<string | number, T>();
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;
};