routes.js 4.74 KB
import { constantRoutes } from '@/router'
import { getRouterList } from '@/api/router'
import { convertRouter } from '@/utils/handleRoutes'

const state = () => ({
  // 路由列表
  routes: [],
  // 是否以全屏幕模式打开(即:不显示头部、底部、侧边栏等区域)
  fullScreenState: false,
  menus: [],
})
const getters = {
  routes: (state) => state.routes,
  fullScreenState: (state) => state.fullScreenState,
}
const mutations = {
  setAllRoutes(state, routes) {
    state.routes = constantRoutes.concat(routes)
  },
  setFullScreenState(state, fullScreenState) {
    state.fullScreenState = fullScreenState
  },
  cleanRoutes(state) {
    state.routes = []
  },
  setAllMenus(state, menus) {
    state.menus = menus
  },
}

const method = {
  //查找路由及其子路由中不为noRedirect的path,并将重定向的菜单改为不可关闭
  getPathNoRedirect(route){
    if(route.type != 'catalog' && !['noRedirect','index'].includes(route.redirect)){
      //将重定向的菜单改为不可关闭
      route.meta.affix=true
      return route.path
    }
    let path = route.path||''
    if (path == '*') {
      path = ''
    }
    if(route.children && route.children.length > 0){
      for(let i=0;i<route.children.length;i++){
        const r=route.children[i]
        //拼接父菜单路径
        if(r.path.indexOf('/') == 0){
          r.path = path + r.path
        } else {
          r.path = path + '/' + r.path
        }
        if(r.type != 'catalog' && r.redirect !== 'noRedirect' && !r.hidden){
          //将重定向的菜单改为不可关闭
          r.meta.affix=true
          path = r.path
          break
        }
        path = method.getPathNoRedirect(r)
      }
    }
    if(path.includes('//')){
      path = path.replaceAll('//', '/')
    }
    return path
  },
  //判断路由列表中是否包含指定的名称(主要用来查是否包含首页)
  containsRouteName(routes, name){
    var result=null
    if(routes && routes.length > 0){
      routes.forEach(item=>{
        if(item.name === name || method.containsRouteName(item.children, name)){
          result = item
          return
        }
      })
    }
    return result
  }
}


const actions = {
  async setAllRoutes({ commit }) {
    let { value } = await getRouterList()
    const newVale = JSON.parse(JSON.stringify(value))
    // 通配符路由必须添加在最后
    //value.push({ path: '*', redirect: '/404', hidden: true })
    newVale.forEach((item) => {
      const routeExtend =
        (item.routeExtend && JSON.parse(item.routeExtend)) || {}
      if (routeExtend.meta) {
        routeExtend.meta.menuLevel = 'first'
        item.routeExtend = JSON.stringify(routeExtend)
      }
      if (item.children && item.children.length) {
        item.children.forEach((child) => {
          const childrenRouteExtend =
            (child.routeExtend && JSON.parse(child.routeExtend)) || {}
          if (childrenRouteExtend.meta) {
            childrenRouteExtend.meta.menuLevel = 'second'
            child.routeExtend = JSON.stringify(childrenRouteExtend)
          } else if (child.href) {
            child.menuLevel = 'second'
          }
        })
      }
    })
    let accessRoutes = convertRouter(newVale)
    //如果没有任何路由权限,最后添加403通配符
    let redirect='/403'
    // if(accessRoutes && accessRoutes.length > 0 && !method.containsRouteName(accessRoutes, 'Index')){
    //   redirect = method.getPathNoRedirect(accessRoutes[0])
    // }
    if(accessRoutes && accessRoutes.length > 0){
      // 如果存在首页,通配符路由改为首页;否则取第一个菜单做通配符路由
      var routeIndex=method.containsRouteName(accessRoutes,'Index')
      if(routeIndex){
        if(routeIndex.path == '/'){
          routeIndex.path='/index'
        }
      } else {
        // 遍历路由列表,查找到第一个页面或者包含子节点的目录
        let firstRoute = accessRoutes[0]
        for (let i=0;i<accessRoutes.length;i++){
          const route = accessRoutes[i]
          if(route.type != 'catalog'){
            firstRoute = route
            break;
          }
          if(route.type == 'catalog' && route.children && route.children.length > 0){
            firstRoute = route
            break;
          }
        }
        redirect = method.getPathNoRedirect(firstRoute)
      }
    }
    accessRoutes.push({
      path: '*',
      redirect: redirect,
      hidden: true,
    })
    commit('setAllMenus', value)
    commit('setAllRoutes', accessRoutes)
    return accessRoutes
  },
  setFullScreenState({ commit }, fullScreenState) {
    commit('setFullScreenState', fullScreenState)
    return fullScreenState
  },
  cleanRoutes({ commit }) {
    commit('cleanRoutes')
  },
}
export default { state, getters, mutations, actions }