import type { RouteRecordRaw } from 'vue-router';
|
|
import { useAccess } from '@vben/access';
|
import { useAccessStore, useUserStore } from '@vben/stores';
|
|
/** 首页常驻,业务数据和入口仍需遵循当前用户的菜单权限。 */
|
export function useHomeAccess() {
|
const accessStore = useAccessStore();
|
const userStore = useUserStore();
|
const { hasAccessByCodes } = useAccess();
|
|
/**
|
* 接口权限:没有对应权限码就取不到数,请求会直接 403,所以取数前先问一句。
|
*
|
* 后端 `@ss.hasPermission` 对超管是直接放行的(不看权限码),前端这里保持一致,
|
* 否则超管会因为权限码没在菜单里配而少看到卡片。
|
*/
|
function canQuery(permission: string) {
|
return (
|
userStore.userRoles.includes('super_admin') ||
|
hasAccessByCodes([permission, '*:*:*'])
|
);
|
}
|
|
/**
|
* 该菜单对当前用户是否「开着」—— 用于首页模块开关。
|
*
|
* 后端菜单 `visible = 0` 会被前端转成路由的 `meta.hideInMenu`,这类路由仍然注册在
|
* router 里(页面可以直接访问),只是整棵子树不会出现在侧边栏。所以判断「这个模块有
|
* 没有开」不能只看路由是否存在,还要看它和它的每一级祖先是否可见。
|
*
|
* @param name 路由 name,即后端菜单的 component_name
|
*/
|
function canSeeMenu(name: string) {
|
function find(
|
routes: RouteRecordRaw[],
|
ancestorHidden: boolean,
|
): boolean | undefined {
|
for (const route of routes) {
|
const hidden =
|
ancestorHidden ||
|
route.meta?.hideInMenu === true ||
|
route.meta?.menuVisibleWithForbidden === true;
|
if (route.name === name) return !hidden;
|
const found = find(route.children ?? [], hidden);
|
if (found !== undefined) return found;
|
}
|
return undefined;
|
}
|
return find(accessStore.accessRoutes, false) === true;
|
}
|
|
return { canQuery, canSeeMenu };
|
}
|