import request, { getToken } from '/@/utils/request';
|
import { GetUserMenuTree } from '/@/api/login/index.js';
|
import { MenuTypeEnum } from '/@/api/menu/type';
|
import { PathRouteType } from '/@/router/pathMap';
|
/**
|
* 以下为模拟接口地址,gitee 的不通,就换自己的真实接口地址
|
*
|
* (不建议写成 request.post(xxx),因为这样 post 时,无法 params 与 data 同时传参)
|
*
|
* 后端控制菜单模拟json,路径在 https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu
|
* 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
* @method getAdminMenu 获取后端动态路由菜单(admin)
|
* @method getTestMenu 获取后端动态路由菜单(test)
|
*/
|
export function useMenuApi() {
|
return {
|
// getAdminMenu: (params?: object) => {
|
// return request({
|
// url: '/src/api/istation/menuData.js',
|
// method: 'get',
|
// params,
|
// });
|
// },
|
getAdminMenu: GetUserMenuTree,
|
|
getTestMenu: (params?: object) => {
|
return request({
|
url: '/gitee/lyt-top/vue-next-admin-images/raw/master/menu/testMenu.json',
|
method: 'get',
|
params,
|
});
|
},
|
};
|
}
|
|
const menuProps = {
|
ID: 'id',
|
ParentID: 'pid',
|
Type: 'type',
|
Name: 'title',
|
Path: 'path',
|
Component: 'component',
|
Redirect: 'redirect',
|
Permission: 'permission',
|
Icon: 'icon',
|
IsIframe: 'isIframe',
|
OutLink: 'isLink',
|
IsHide: 'isHide',
|
IsKeepAlive: 'isKeepAlive',
|
IsAffix: 'isAffix',
|
Weight: 'weight',
|
SortCode: 'orderNo',
|
Description: 'remark',
|
Children: 'children',
|
};
|
|
const metaProps = ['Name', 'Icon', 'IsIframe', 'OutLink', 'IsHide', 'IsKeepAlive', 'IsAffix'];
|
// 找到类型为菜单的菜单,用于跳转
|
const findPathMenu = (menu) => {
|
if (menu.type === MenuTypeEnum.Catalogue) {
|
if (menu.children && menu.children.length > 0) {
|
return findPathMenu(menu.children[0]);
|
// 目录下面还没有子菜单
|
} else {
|
return '/notFound';
|
}
|
} else if (menu.type === MenuTypeEnum.Menu) {
|
return menu.path || '/notFound';
|
// 其余菜单类型
|
} else {
|
return '/notFound';
|
}
|
};
|
|
const setCataloguePaths = (treeData: any[]) => {
|
for (const item of treeData) {
|
if (item.type === MenuTypeEnum.Catalogue) {
|
if (item.children && item.children.length !== 0) {
|
setCataloguePaths(item.children);
|
}
|
// 顶部菜单跳转至下层
|
if (item.rootId === item.id) {
|
item.path = findPathMenu(item);
|
// 底部左侧菜单,保证唯一性
|
} else {
|
const firstChildIsHide = item?.children?.[0]?.meta?.isHide;
|
// 下层有个隐藏菜单,它的 path 应该就是指向它
|
if (firstChildIsHide) {
|
item.path = findPathMenu(item);
|
} else {
|
item.path = '/' + item.id;
|
}
|
}
|
} else {
|
item.path = findPathMenu(item);
|
}
|
}
|
};
|
/**
|
* 检查 outLink 上是否有关键字,比如 {token},将其替换为实际的 token
|
* @param menu
|
*/
|
const handleLinkMenu = (menu) => {
|
const splitArr = menu.OutLink.split('?');
|
const params = splitArr.at(-1);
|
const urlArr = splitArr.slice(0, -1);
|
if (params) {
|
if (/{\s*token\s*\}/.test(params)) {
|
const token = getToken();
|
const newParams = params.replace(/(?<=\s*=\s*)\{\s*token\s*\}/, token);
|
urlArr.push(newParams);
|
const newOutLink = urlArr.join('?');
|
menu.OutLink = newOutLink;
|
}
|
}
|
};
|
|
export const parseMenuTree = (menuTree: any[], pathMap: Map<String, PathRouteType>) => {
|
// rootId 记录根菜单的 ID,根菜单本身的 rootId 为自己
|
const travelMenuTree = (menuTreeList: any[], rootId = null) => {
|
return menuTreeList.map((item) => {
|
const result = { meta: {} };
|
// 检查带外链的网页,替换 url 参数中的特殊标志
|
if (item.OutLink) {
|
handleLinkMenu(item);
|
}
|
for (const itemKey in item) {
|
if (metaProps.includes(itemKey)) {
|
result.meta[menuProps[itemKey]] = item[itemKey];
|
} else {
|
result[menuProps[itemKey]] = item[itemKey];
|
}
|
}
|
const resultAny = result as any;
|
|
// 记录当前根菜单的路由 id
|
resultAny.rootId = rootId === null ? item.ID : rootId;
|
switch (item.Type) {
|
case MenuTypeEnum.Menu:
|
if (!item.Path) {
|
break;
|
}
|
// 给菜单加入其对应的 component 等属性
|
const pathRoute = pathMap.get(item.Path);
|
if (pathRoute) {
|
resultAny.component = pathRoute.component;
|
// 命名路由
|
resultAny.name = pathRoute.name;
|
resultAny.redirect = pathRoute.redirect;
|
|
resultAny.meta.isAffix = pathRoute.isAffix;
|
resultAny.meta.isKeepAlive = pathRoute.isKeepAlive;
|
|
// 将 pathMap 的 value 置为当前 result
|
pathMap.set(item.Path, result as any);
|
}
|
break;
|
case MenuTypeEnum.Catalogue:
|
if (item.Children && item.Children.length !== 0) {
|
resultAny.children = travelMenuTree(item.Children, resultAny.rootId);
|
}
|
break;
|
default:
|
break;
|
}
|
|
return result;
|
});
|
};
|
const treeData = travelMenuTree(menuTree);
|
setCataloguePaths(treeData);
|
return treeData;
|
};
|