handleRoutes.js 5.76 KB
import { templatePreviewKeepalive, querySqlPreviewKeepalive } from '@/config'

import store from '@/store'

const getAccount = () => {
  const account = store.getters['user/account']
  return account
}
const ignoreField = [
  'activeTab',
  // 'alias',
  'id',
  'menuIcon',
  'pkVal',
  'sn',
  'sysMethods',
  'tabsStyle',
  'tenantId',
  'parentId',
]

// 需要实现keepalive的路由列表
const keepaliveRoutes = []

if (templatePreviewKeepalive) {
  keepaliveRoutes.push({
    alias: 'templatePreview',
    name: 'TemplatePreview',
  })
}

if (querySqlPreviewKeepalive) {
  keepaliveRoutes.push({
    alias: 'querySqlPreview',
    name: 'QuerySqlPreview',
  })
}

const getAllComponentsNameUnderViews = () => {
  const viewsComponents = require.context('@/views', true, /\.vue$/)
  const nameList = []
  viewsComponents.keys().map((item) => {
    const componentConfig = viewsComponents(item)
    nameList.push(componentConfig.default.name)
  })
  return nameList
}

const getKeepaliveMenu = (route) => {
  //将菜单别名首字母转成大写
  const newAlias = route.alias.replace(
    route.alias[0],
    route.alias[0].toUpperCase()
  )
  if (
    route.isRefresh === 0 &&
    getAllComponentsNameUnderViews().includes(newAlias)
  ) {
    keepaliveRoutes.push({ alias: route.alias, name: newAlias })
  }
  localStorage.setItem(
    `keepalive_${getAccount()}`,
    JSON.stringify(keepaliveRoutes)
  )
}

// 注册的路由name可能与组件的Name不一致,需要修改route的name与组件的name保持一致才能让keepalive生效
const keepaliveTransfer = (route) => {
  if (!route.alias) {
    return
  }
  const matchRoute = keepaliveRoutes.find((r) => r.alias == route.alias)
  if (matchRoute && matchRoute.name) {
    route.name = matchRoute.name
  }
}

// 路由对应的Component转换处理
const componentTransfer = (route) => {
  if (!route.component) {
    return
  }
  if (route.component === 'Layout') {
    route.component = (resolve) => require(['@/components/layouts'], resolve)
  } else if (route.component === 'EmptyLayout') {
    route.component = (resolve) =>
      require(['@/components/layouts/EmptyLayout'], resolve)
  } else if (route.component === 'DatavLayout') {
    route.component = (resolve) =>
      require(['@/components/datav/DatavDesignPreview.vue'], resolve)
  } else if (route.component === 'TemplateLayout') {
    // 注册为keepalive的路由
    templatePreviewKeepalive && registerKeepaliveRoute(route, 'TemplatePreview')
    route.component = (resolve) =>
      require(['@/components/dataTemplate/TemplatePreview.vue'], resolve)
  } else if (route.component === 'QuerySqlLayout') {
    // 注册为keepalive的路由
    querySqlPreviewKeepalive && registerKeepaliveRoute(route, 'QuerySqlPreview')
    route.component = (resolve) =>
      require(['@/components/querySql/QuerySqlPreview.vue'], resolve)
  } else if (route.component === 'indexLayout') {
    route.component = (resolve) => require(['@/views/home/index'], resolve)
  } else if (route.component === 'OnlineMenu') {
    route.component = (resolve) => require(['@/views/OnlineMenu'], resolve)
  } else if (route.component === 'MultilevelMenuLayout') {
    route.component = (resolve) =>
      require(['@/components/layouts/MultilevelMenuLayout'], resolve)
  } else {
    const index = route.component.indexOf('views')
    const path =
      index > 0 ? route.component.slice(index) : `views/${route.component}`
    route.component = (resolve) => require([`@/${path}`], resolve)
  }
}

/**
 * 注册需要keepalive的路由
 */
const registerKeepaliveRoute = (route, name) => {
  if (!route || !route.path) {
    return
  }
  route.name = name
}

/**
 * 后台传过来的路由需要转换
 * @param {*} asyncRoutes
 * @returns
 */
export function convertRouter(asyncRoutes) {
  let r = asyncRoutes
  let routePaths = []
  for (let i = r.length - 1; i >= 0; i--) {
    let route = r[i]
    //获取需要缓存的菜单
    getKeepaliveMenu(route)
    // keepalive的路由处理
    keepaliveTransfer(route)
    let extend = (route.routeExtend && JSON.parse(route.routeExtend)) || {
      ...route,
      meta: {
        title: route.name,
        href: route.href,
        menuLevel: route.parentId && route.parentId == '3' ? 'first' : '',
        isChildren: route.parentId && route.parentId == '3' ? false : true,
      },
      component: 'OnlineMenu',
      path: `/onlineMenu/${getCurrentPath(route.path)}`,
    }
    !route.href && delete route.href
    delete route.routeExtend
    Object.keys(extend).forEach((key) => {
      route[key] = extend[key]
    })
    ignoreField.forEach((field) => {
      delete route[field]
    })
    //处理路由中的参数
    let path = route.path
    if (path.indexOf('?') !== -1) {
      const paths = path.split('?')
      if (paths.length > 1) {
        let routerParams = {}
        const params = paths[1].split('&')
        if (params.length > 0) {
          params.forEach((param) => {
            const paraValues = param.split('=')
            routerParams[paraValues[0]] = paraValues[1]
          })
        }
        route.path = paths[0]
        route.meta = { ...route.meta, ...routerParams }
      }
    }
    if (routePaths.includes(route.path)) {
      console.error(`存在相同的路由路径[${route.path}]`)
      r.splice(i, 1)
    } else {
      routePaths.push(route.path)
    }
    // 路由对应的Component的转换处理
    componentTransfer(route)
    if (route.children && route.children.length) {
      route.children = convertRouter(route.children)
    }
    if (route.children && route.children.length === 0) delete route.children
  }
  return r
}
function getCurrentPath(path) {
  const onlineMenuPath = path.split('.')
  return onlineMenuPath[onlineMenuPath.length - 2]
}

export const keepaliveIncludes = keepaliveRoutes.reduce((ary, cur) => {
  ary.push(cur.name)
  return ary
}, [])