108 lines
2.8 KiB
TypeScript
108 lines
2.8 KiB
TypeScript
/**
|
||
* 菜单数据转换工具,将API返回的菜单数据转换为前端使用的格式
|
||
*/
|
||
|
||
// API返回的菜单项类型
|
||
export interface ApiMenuItem {
|
||
menuId: string;
|
||
parentId: string;
|
||
menuName: string;
|
||
menuType: string; // 'catalog' | 'route'
|
||
orderNum: number;
|
||
visible: string;
|
||
children?: ApiMenuItem[];
|
||
[key: string]: any; // 其他可能的字段
|
||
}
|
||
|
||
// 前端需要的菜单项类型
|
||
export interface FrontendMenuItem {
|
||
id: number | string;
|
||
parentId: number | string;
|
||
title: string;
|
||
type: number; // 1表示目录,2表示菜单
|
||
path: string;
|
||
name: string;
|
||
component: string;
|
||
icon: string;
|
||
isExternal: boolean;
|
||
isCache: boolean;
|
||
isHidden: boolean;
|
||
sort: number;
|
||
children?: FrontendMenuItem[];
|
||
}
|
||
|
||
/**
|
||
* 转换菜单类型: catalog -> 1, route -> 2
|
||
*/
|
||
const convertMenuType = (menuType: string): number => {
|
||
switch (menuType.toLowerCase()) {
|
||
case 'catalog':
|
||
return 1;
|
||
case 'route':
|
||
return 2;
|
||
case 'button':
|
||
return 3;
|
||
default:
|
||
// 默认为菜单类型
|
||
return 2;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 是否隐藏: '0' -> false, '1' -> true
|
||
*/
|
||
const convertVisible = (visible: string): boolean => {
|
||
return visible === '1'; // '1'为隐藏,'0'为显示
|
||
}
|
||
|
||
/**
|
||
* 转换单个菜单项
|
||
*/
|
||
const convertMenuItem = (apiItem: ApiMenuItem): FrontendMenuItem => {
|
||
// 根据menuType生成默认的path和component
|
||
let path = '';
|
||
let component = '';
|
||
let name = '';
|
||
|
||
// 简单的名称生成,去掉空格,保持首字母大写,非首字母小写
|
||
const generateName = (menuName: string): string => {
|
||
return menuName.replace(/\s+/g, '')
|
||
.replace(/^./, (match) => match.toUpperCase())
|
||
.replace(/[\u4e00-\u9fa5]/g, ''); // 移除中文字符
|
||
};
|
||
|
||
if (apiItem.menuType.toLowerCase() === 'catalog') {
|
||
path = `/${apiItem.menuName.toLowerCase().replace(/\s+/g, '-')}`;
|
||
component = 'Layout';
|
||
name = generateName(apiItem.menuName);
|
||
} else {
|
||
// 假设route类型菜单都在某个catalog下
|
||
const parentName = apiItem.menuName.toLowerCase().replace(/\s+/g, '-');
|
||
path = `/system/${parentName}`;
|
||
component = `system/${parentName}/index`;
|
||
name = `System${generateName(apiItem.menuName)}`;
|
||
}
|
||
|
||
return {
|
||
id: apiItem.menuId,
|
||
parentId: apiItem.parentId,
|
||
title: apiItem.menuName,
|
||
type: convertMenuType(apiItem.menuType),
|
||
path: path,
|
||
name: name,
|
||
component: component,
|
||
icon: 'settings', // 默认图标
|
||
isExternal: false,
|
||
isCache: false,
|
||
isHidden: convertVisible(apiItem.visible),
|
||
sort: apiItem.orderNum || 0,
|
||
children: apiItem.children ? apiItem.children.map(child => convertMenuItem(child)) : []
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 转换API返回的菜单数据为前端需要的格式
|
||
*/
|
||
export const convertMenuData = (apiMenuData: ApiMenuItem[]): FrontendMenuItem[] => {
|
||
return apiMenuData.map(item => convertMenuItem(item));
|
||
}
|