160 lines
4.5 KiB
Plaintext
160 lines
4.5 KiB
Plaintext
import { toRaw, unref } from 'vue';
|
|
import { defineStore } from 'pinia';
|
|
import { RouteRecordRaw } from 'vue-router';
|
|
import { store } from '@/store';
|
|
import { asyncRoutes, constantRouter } from '@/router/index';
|
|
import { generatorDynamicRouter } from '@/router/generator-routers';
|
|
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
|
import { isUrl } from '@/utils';
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
interface TreeHelperConfig {
|
|
id: string;
|
|
children: string;
|
|
pid: string;
|
|
}
|
|
|
|
const DEFAULT_CONFIG: TreeHelperConfig = {
|
|
id: 'id',
|
|
children: 'children',
|
|
pid: 'pid',
|
|
};
|
|
|
|
const getConfig = (config: Partial<TreeHelperConfig>) => Object.assign({}, DEFAULT_CONFIG, config);
|
|
|
|
export interface IAsyncRouteState {
|
|
menus: RouteRecordRaw[];
|
|
routers: any[];
|
|
addRouters: any[];
|
|
keepAliveComponents: string[];
|
|
isDynamicAddedRoute: boolean;
|
|
}
|
|
|
|
function filter<T = any>(
|
|
tree: T[],
|
|
func: (n: T) => boolean,
|
|
config: Partial<TreeHelperConfig> = {},
|
|
): T[] {
|
|
config = getConfig(config);
|
|
const children = config.children as string;
|
|
|
|
function listFilter(list: T[]) {
|
|
return list
|
|
.map((node: any) => ({ ...node }))
|
|
.filter((node) => {
|
|
node[children] = node[children] && listFilter(node[children]);
|
|
return func(node) || (node[children] && node[children].length);
|
|
});
|
|
}
|
|
|
|
return listFilter(tree);
|
|
}
|
|
|
|
function formatRelativePath(menus, parent?) {
|
|
// 计算路由绝对路径
|
|
return cloneDeep(menus).map((route) => {
|
|
// if (parent) {
|
|
// route.path = `${parent.path || ''}/${route.path}`;
|
|
// } else {
|
|
// route.path = `/${route.path}`;
|
|
// }
|
|
// route.path = route.path.replace('//', '/');
|
|
//如果是外部地址,特殊处理
|
|
if (route.meta?.target && isUrl(route.name)) {
|
|
route.path = route.name;
|
|
}
|
|
// format children routes
|
|
if (route.children && route.children.length > 0) {
|
|
route.children = formatRelativePath(route.children, route);
|
|
}
|
|
return route;
|
|
});
|
|
}
|
|
|
|
export const useAsyncRouteStore = defineStore({
|
|
id: 'app-async-route',
|
|
state: (): IAsyncRouteState => ({
|
|
menus: [],
|
|
routers: constantRouter,
|
|
addRouters: [],
|
|
keepAliveComponents: [],
|
|
// Whether the route has been dynamically added
|
|
isDynamicAddedRoute: false,
|
|
}),
|
|
getters: {
|
|
getMenus(): RouteRecordRaw[] {
|
|
return formatRelativePath(this.menus);
|
|
},
|
|
getIsDynamicAddedRoute(): boolean {
|
|
return this.isDynamicAddedRoute;
|
|
},
|
|
getRouters() {
|
|
return toRaw(this.addRouters);
|
|
},
|
|
},
|
|
actions: {
|
|
//从缓存列表删除路由
|
|
removeKeepAliveComponents(compNames) {
|
|
if (!compNames || !compNames.length) return;
|
|
this.keepAliveComponents = this.keepAliveComponents.filter(
|
|
(item) => !compNames.includes(item),
|
|
);
|
|
},
|
|
setDynamicAddedRoute(added: boolean) {
|
|
this.isDynamicAddedRoute = added;
|
|
},
|
|
// 设置动态路由
|
|
setRouters(routers) {
|
|
this.addRouters = routers;
|
|
this.routers = constantRouter.concat(routers);
|
|
},
|
|
setMenus(menus) {
|
|
// 设置动态路由
|
|
this.menus = menus;
|
|
},
|
|
setKeepAliveComponents(compNames) {
|
|
// 设置需要缓存的组件
|
|
this.keepAliveComponents = compNames;
|
|
},
|
|
async generateRoutes(data) {
|
|
let accessedRouters;
|
|
const permissionsList = data.permissions || [];
|
|
const routeFilter = (route) => {
|
|
const { meta } = route;
|
|
const { permissions, authEvery } = meta || {};
|
|
if (!permissions) return true;
|
|
if (authEvery === true) {
|
|
return permissionsList.every((item) => permissions.includes(item.value));
|
|
}
|
|
return permissionsList.some((item) => permissions.includes(item.value));
|
|
};
|
|
const { getPermissionMode } = useProjectSetting();
|
|
const permissionMode = unref(getPermissionMode);
|
|
if (permissionMode === 'BACK') {
|
|
// 动态获取菜单
|
|
try {
|
|
accessedRouters = await generatorDynamicRouter();
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
} else {
|
|
try {
|
|
//过滤账户是否拥有某一个权限,并将菜单从加载列表移除
|
|
accessedRouters = filter(asyncRoutes, routeFilter);
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
}
|
|
accessedRouters = accessedRouters.filter(routeFilter);
|
|
this.setRouters(accessedRouters);
|
|
this.setMenus(accessedRouters);
|
|
return toRaw(accessedRouters);
|
|
},
|
|
},
|
|
});
|
|
|
|
// Need to be used outside the setup
|
|
export function useAsyncRouteStoreWidthOut() {
|
|
return useAsyncRouteStore(store);
|
|
}
|