permission.js 4.16 KB
import {getMenuTree} from '@/api/moudles/uc/auth';
import {
    constantRoutes,
    asyncRoutes
} from '@/router';
import {deepClone, getFirstNav} from '@/utils';

/**
 * Use meta.permissions to determine if the current user has permission
 * @param permissions
 * @param route
 */
function hasPermission(permissions, route) {
    if (route.meta && route.meta.permissions) {
        return permissions.some(permission => route.meta.permissions.includes(permission));
    } else {
        return true;
    }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param permissions
 */
export function filterAsyncRoutes(routes, permissions) {
    const res = [];

    routes.forEach(route => {
        const tmp = {
            ...route
        };
        if (hasPermission(permissions, tmp)) {
            if (tmp.children) {
                tmp.children = filterAsyncRoutes(tmp.children, permissions);
            }
            res.push(tmp);
        }
    });

    return res;
}

const state = {
    routes: [],
    addRoutes: [],
    permissions: [],
    menus: [],
    subMenus: [],
    crumbList: []
};

const mutations = {
    SET_ROUTES: (state, routes) => {
        state.addRoutes = routes;
        state.routes = constantRoutes.concat(routes);
    },
    SET_PERMISSIONS: (state, permissions) => {
        state.permissions = permissions;
    },
    SET_MENUS: (state, list) => {
        state.menus = list;
    },
    SET_SUB_MENUS: (state, subMenus) => {
        state.subMenus = deepClone(subMenus);
    },
    SET_CRUMB_LIST: (state, list) => {
        state.crumbList = list;
    }
};

function getAuthCodes(data) {
    let authCodes = [];
    data.forEach(item => {
        authCodes.push(item.code);
        if (item.childList) {
            authCodes = authCodes.concat(getAuthCodes(item.childList));
        } else if (item.buttonList) {
            authCodes = authCodes.concat(getAuthCodes(item.buttonList));
        }
    });
    return authCodes;
}

/**
 * 递归过滤异步路由表,返回符合用户角色权限的路由表
 * @param asyncRouterMap
 * @param permissions
 */
function filterAsyncRouter(asyncRouterMap, permissions) {
    const accessedRouters = asyncRouterMap.filter(route => {
        if (hasPermission(permissions, route)) {
            if (route.children && route.children.length) {
                route.children = filterAsyncRouter(route.children, permissions);
            }
            return true;
        }
        return false;
    });
    return accessedRouters;
}

const actions = {
    setPermissions({
                       commit
                   }, permissions) {
        commit('SET_PERMISSIONS', permissions);
    },
    setCrumbList({
                     commit
                 }, crumbList) {
        commit('SET_CRUMB_LIST', crumbList);
    },
    setSubMenus({
                    commit
                }, subMenus) {
        commit('SET_SUB_MENUS', subMenus);
    },
    generateRoutes({
                       commit
                   }, permissions) {
        return new Promise(resolve => {
            getMenuTree().then(res => {
                if (!res.data || !res.data.childList || res.data.childList.length === 0) {
                    commit('SET_PERMISSIONS', []);
                    resolve([]);
                    return;
                }
                const childList = res.data.childList;

                const authCodes = getAuthCodes(childList);
                commit('SET_PERMISSIONS', authCodes);

                let accessedRoutes;
                if (!authCodes || authCodes.length === 0) {
                    accessedRoutes = [];
                } else {
                    accessedRoutes = filterAsyncRouter(asyncRoutes, authCodes);
                }
                accessedRoutes.push({
                    path: '/',
                    redirect: getFirstNav(childList)
                });
                console.log('accessedRoutes', accessedRoutes);
                commit('SET_MENUS', childList);
                commit('SET_ROUTES', accessedRoutes);
                resolve(accessedRoutes);
            });
        });
    }
};

export default {
    namespaced: true,
    state,
    mutations,
    actions
};