199 lines
5.2 KiB
TypeScript
199 lines
5.2 KiB
TypeScript
import type { RouteRecordStringComponent } from '@vben/types';
|
|
|
|
import { requestClient } from '#/api/request';
|
|
|
|
const SUPPORTED_ADMIN_MENU_NAMES = new Set([
|
|
'Analytics',
|
|
'Blog',
|
|
'BlogArticle',
|
|
'BlogArticleCreate',
|
|
'BlogArticleDelete',
|
|
'BlogArticleEdit',
|
|
'BlogArticleImport',
|
|
'BlogArticlePreview',
|
|
'BlogArticlePreviewButton',
|
|
'BlogCategory',
|
|
'BlogCategoryCreate',
|
|
'BlogCategoryDelete',
|
|
'BlogCategoryEdit',
|
|
'BlogTag',
|
|
'BlogTagCreate',
|
|
'BlogTagDelete',
|
|
'BlogTagEdit',
|
|
'BlogTheme',
|
|
'BlogThemeImport',
|
|
'BlogThemeSave',
|
|
'Dashboard',
|
|
'Profile',
|
|
'QqBot',
|
|
'QqBotAccount',
|
|
'QqBotAccountConfig',
|
|
'QqBotAccountConfigButton',
|
|
'QqBotAccountCreate',
|
|
'QqBotAccountDelete',
|
|
'QqBotAccountEdit',
|
|
'QqBotAccountKick',
|
|
'QqBotAccountMessagePushCreate',
|
|
'QqBotAccountMessagePushDelete',
|
|
'QqBotAccountMessagePushList',
|
|
'QqBotAccountMessagePushToggle',
|
|
'QqBotAccountMessagePushUpdate',
|
|
'QqBotAccountNapcatWebui',
|
|
'QqBotAccountRefreshLogin',
|
|
'QqBotAccountWebUI',
|
|
'QqBotCommand',
|
|
'QqBotCommandCreate',
|
|
'QqBotCommandDelete',
|
|
'QqBotCommandEdit',
|
|
'QqBotCommandTest',
|
|
'QqBotCommandToggle',
|
|
'QqBotConversation',
|
|
'QqBotDashboard',
|
|
'QqBotMessage',
|
|
'QqBotMessageSubscription',
|
|
'QqBotMessageSubscriptionCreate',
|
|
'QqBotMessageSubscriptionDelete',
|
|
'QqBotMessageSubscriptionList',
|
|
'QqBotMessageSubscriptionToggle',
|
|
'QqBotMessageSubscriptionUpdate',
|
|
'QqBotMessageTemplate',
|
|
'QqBotMessageTemplateCreate',
|
|
'QqBotMessageTemplateDelete',
|
|
'QqBotMessageTemplateList',
|
|
'QqBotMessageTemplatePreview',
|
|
'QqBotMessageTemplateToggle',
|
|
'QqBotMessageTemplateUpdate',
|
|
'QqBotPermission',
|
|
'QqBotPermissionCreate',
|
|
'QqBotPermissionDelete',
|
|
'QqBotPermissionEdit',
|
|
'QqBotPlugin',
|
|
'QqBotPluginTask',
|
|
'QqBotPluginTaskDisable',
|
|
'QqBotPluginTaskEnable',
|
|
'QqBotPluginTaskRun',
|
|
'QqBotPluginTaskRunLog',
|
|
'QqBotPluginTaskUpdateCron',
|
|
'QqBotRule',
|
|
'QqBotRuleCreate',
|
|
'QqBotRuleDelete',
|
|
'QqBotRuleEdit',
|
|
'QqBotRuleToggle',
|
|
'QqBotSendGroup',
|
|
'QqBotSendLog',
|
|
'QqBotSendPrivate',
|
|
'System',
|
|
'SystemDept',
|
|
'SystemDeptCreate',
|
|
'SystemDeptDelete',
|
|
'SystemDeptEdit',
|
|
'SystemDict',
|
|
'SystemDictCreate',
|
|
'SystemDictDelete',
|
|
'SystemDictEdit',
|
|
'SystemKtTableDemo',
|
|
'SystemKtTableDemoCreate',
|
|
'SystemKtTableDemoDelete',
|
|
'SystemKtTableDemoEdit',
|
|
'SystemLog',
|
|
'SystemMenu',
|
|
'SystemMenuCreate',
|
|
'SystemMenuDelete',
|
|
'SystemMenuEdit',
|
|
'SystemNetwork',
|
|
'SystemNetworkDdnsCreate',
|
|
'SystemNetworkDdnsDelete',
|
|
'SystemNetworkDdnsList',
|
|
'SystemNetworkDdnsRetry',
|
|
'SystemNetworkDdnsUpdate',
|
|
'SystemNetworkPortForwardCreate',
|
|
'SystemNetworkPortForwardDelete',
|
|
'SystemNetworkPortForwardHistory',
|
|
'SystemNetworkPortForwardKeeper',
|
|
'SystemNetworkPortForwardList',
|
|
'SystemNetworkPortForwardProbe',
|
|
'SystemNetworkPortForwardRetry',
|
|
'SystemNetworkPortForwardUpdate',
|
|
'SystemNotice',
|
|
'SystemNoticeDelete',
|
|
'SystemNoticeEdit',
|
|
'SystemRole',
|
|
'SystemRoleCreate',
|
|
'SystemRoleDelete',
|
|
'SystemRoleEdit',
|
|
'SystemUser',
|
|
'SystemUserCreate',
|
|
'SystemUserDelete',
|
|
'SystemUserEdit',
|
|
]);
|
|
|
|
export function isSupportedAdminMenuName(name?: null | string | symbol) {
|
|
return typeof name === 'string' && SUPPORTED_ADMIN_MENU_NAMES.has(name);
|
|
}
|
|
|
|
/**
|
|
* 将后端数据库排序字段对齐到 Vben 菜单生成器实际读取的 `meta.order`。
|
|
* @param menu - `/menu/all` 返回的后端菜单节点;节点可能同时带有历史路由 `meta.order` 和 DB `sort`。
|
|
* @returns 克隆后的菜单节点;当后端提供有限数字 `sort` 时以 DB 排序为准,否则保留原节点。
|
|
*/
|
|
function normalizeBackendMenuOrder(
|
|
menu: RouteRecordStringComponent,
|
|
): RouteRecordStringComponent {
|
|
const sortOrder =
|
|
typeof menu.sort === 'number' && Number.isFinite(menu.sort)
|
|
? menu.sort
|
|
: undefined;
|
|
|
|
if (sortOrder === undefined) {
|
|
return menu;
|
|
}
|
|
|
|
const meta = menu.meta ?? { title: String(menu.name ?? '') };
|
|
|
|
return {
|
|
...menu,
|
|
meta: {
|
|
...meta,
|
|
order: sortOrder,
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 过滤当前 Admin 已实现的后端菜单,并保留后端排序语义给路由菜单生成器使用。
|
|
* @param menus - `/menu/all` 返回的后端菜单树;包含页面节点、隐藏路由节点和按钮权限节点。
|
|
* @returns 仅含当前前端支持节点的菜单树,且每个节点的 DB `sort` 已映射为权威 `meta.order`。
|
|
*/
|
|
function filterSupportedAdminMenus(
|
|
menus: RouteRecordStringComponent[],
|
|
): RouteRecordStringComponent[] {
|
|
return menus
|
|
.map((menu) => {
|
|
const normalizedMenu = normalizeBackendMenuOrder(menu);
|
|
const children = normalizedMenu.children
|
|
? filterSupportedAdminMenus(normalizedMenu.children)
|
|
: undefined;
|
|
const menuWithoutChildren = { ...normalizedMenu };
|
|
delete menuWithoutChildren.children;
|
|
|
|
return {
|
|
...menuWithoutChildren,
|
|
...(children && children.length > 0 ? { children } : {}),
|
|
};
|
|
})
|
|
.filter(
|
|
(menu) => isSupportedAdminMenuName(menu.name) || !!menu.children?.length,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 获取用户所有菜单
|
|
*/
|
|
export async function getAllMenusApi() {
|
|
const menus =
|
|
await requestClient.get<RouteRecordStringComponent[]>('/menu/all');
|
|
|
|
// 只暴露当前前端页面和后端接口已经支撑的后台菜单。
|
|
return filterSupportedAdminMenus(menus);
|
|
}
|