build: init
This commit is contained in:
150
template/src/utils/menu.tsx
Normal file
150
template/src/utils/menu.tsx
Normal file
@@ -0,0 +1,150 @@
|
||||
import { metaInfo } from '@/meta';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
export type MenuItem = {
|
||||
key: string;
|
||||
label: string | React.ReactElement;
|
||||
disabled?: boolean;
|
||||
icon?: React.ReactNode;
|
||||
children?: MenuItem[];
|
||||
_order?: number;
|
||||
};
|
||||
|
||||
const formatDisplayName = (displayName: string) => {
|
||||
// 用 {{xxx}} 包起来的字符串需要处理国际化
|
||||
if (/^{{(.*)}}$/.test(displayName)) {
|
||||
const key = displayName.match(/^{{(.*)}}$/)![1].trim();
|
||||
return <FormattedMessage id={key} />;
|
||||
}
|
||||
|
||||
return displayName;
|
||||
};
|
||||
|
||||
const flatten = (info: Meta[]) => {
|
||||
const result: Meta[] = [];
|
||||
info.forEach((item) => {
|
||||
if (item._children?.length) {
|
||||
result.push(...flatten(item._children));
|
||||
} else {
|
||||
result.push(item);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const deeplySortMenu = (menus: MenuItem[]) => {
|
||||
const newMenus = [...menus];
|
||||
newMenus.sort((a, b) => a._order! - b._order!);
|
||||
newMenus.forEach((menu) => {
|
||||
if (menu.children) {
|
||||
menu.children = deeplySortMenu(menu.children);
|
||||
}
|
||||
});
|
||||
return newMenus;
|
||||
};
|
||||
|
||||
const getMenuItems = (): MenuItem[] => {
|
||||
const menus: MenuItem[] = [];
|
||||
const flatMetaInfo = flatten(metaInfo);
|
||||
|
||||
// head
|
||||
flatMetaInfo.forEach((item) => {
|
||||
if (!item.headMenu) return;
|
||||
// 非路由页面头部菜单
|
||||
if (typeof item.headMenu !== 'boolean') {
|
||||
const find = menus.find(
|
||||
(menu) => menu.key === (item.headMenu as any)?.key,
|
||||
);
|
||||
if (!find) {
|
||||
menus.push({
|
||||
key: (item.headMenu as any)?.key,
|
||||
label: formatDisplayName((item.headMenu as any)?.label),
|
||||
_order: (item.headMenu as any)?.order ?? 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 路由页面头部菜单
|
||||
if (item.headMenu === true) {
|
||||
menus.push({
|
||||
key: item._fullpath ?? '',
|
||||
label: formatDisplayName(item.displayName ?? ''),
|
||||
_order: item.order ?? 0,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// side
|
||||
flatMetaInfo.forEach((item) => {
|
||||
if (!item.sideMenu) return;
|
||||
|
||||
const head = menus.find((menu) => menu.key === (item.headMenu as any)?.key);
|
||||
if (!head) return;
|
||||
if (!head.children) head.children = [];
|
||||
|
||||
// 非路由页面侧边菜单(分组)
|
||||
if (typeof item.sideMenu !== 'boolean') {
|
||||
const find = head.children.find(
|
||||
(menu) => menu.key === (item.sideMenu as any)?.key,
|
||||
);
|
||||
if (!find) {
|
||||
head.children.push({
|
||||
key: (item.sideMenu as any)?.key,
|
||||
label: formatDisplayName((item.sideMenu as any)?.label),
|
||||
_order: (item.sideMenu as any)?.order,
|
||||
children: [
|
||||
{
|
||||
key: item._fullpath ?? '',
|
||||
label: formatDisplayName(item.displayName ?? ''),
|
||||
_order: item.order ?? 0,
|
||||
},
|
||||
],
|
||||
});
|
||||
} else {
|
||||
find.children!.push({
|
||||
key: item._fullpath ?? '',
|
||||
label: formatDisplayName(item.displayName ?? ''),
|
||||
_order: item.order ?? 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
// 路由页面侧边菜单
|
||||
if (item.sideMenu === true) {
|
||||
head.children.push({
|
||||
key: item._fullpath ?? '',
|
||||
label: formatDisplayName(item.displayName ?? ''),
|
||||
_order: item.order ?? 0,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// sort
|
||||
return deeplySortMenu(menus);
|
||||
};
|
||||
|
||||
export const menuItems = getMenuItems();
|
||||
|
||||
export const findHeadMenuByHeadKey = (headKey) => {
|
||||
return menuItems.find((menu) => menu.key === headKey);
|
||||
};
|
||||
|
||||
export const findHeadMenuBySideKey = (
|
||||
sideKey: string,
|
||||
menus: MenuItem[] = menuItems,
|
||||
): MenuItem | null => {
|
||||
const find = menus.find((menu) =>
|
||||
menu.children?.some(
|
||||
(child) =>
|
||||
child.key === sideKey ||
|
||||
!!findHeadMenuBySideKey(sideKey, menu.children ?? []),
|
||||
),
|
||||
);
|
||||
if (find) return find;
|
||||
return null;
|
||||
};
|
||||
|
||||
export const findFirstSubMenu = (menu: MenuItem): MenuItem | undefined => {
|
||||
if (!menu?.children?.[0]?.children?.length) return menu?.children?.[0];
|
||||
return findFirstSubMenu(menu.children[0]);
|
||||
};
|
||||
Reference in New Issue
Block a user