text: import routerMap from '@/router/async/router.map'
  import { mergeI18nFromRoutes } from '@/utils/i18n'
  import Router from 'vue-router'
  import deepMerge from 'deepmerge'
  import basicOptions from '@/router/async/config.async'
  
  //应用配置
  let appOptions = {
    router: undefined,
    i18n: undefined,
    store: undefined
  }
  
  /**
   * 设置应用配置
   * @param options
   */
  function setAppOptions(options) {
    const { router, store, i18n } = options
    appOptions.router = router
    appOptions.store = store
    appOptions.i18n = i18n
  }
  
  /**
   * 根据 路由配置 和 路由组件注册 解析路由
   * @param routesConfig 路由配置
   * @param routerMap 本地路由组件注册配置
   */
  function parseRoutes(routesConfig, routerMap) {
    let routes = []
    routesConfig.forEach(item => {
      // 获取注册在 routerMap 中的 router，初始化 routeCfg
      let router = undefined,
        routeCfg = {}
      if (typeof item === 'string') {
        router = routerMap[item]
        routeCfg = { path: router.path || item, router: item }
      } else if (typeof item === 'object') {
        router = routerMap[item.router]
        routeCfg = item
      }
      if (!router) {
        console.warn(
          `can't find register for router ${routeCfg.router}, please register it in advance.`
        )
        router = typeof item === 'string' ? { path: item, name: item } : item
      }
      // 从 router 和 routeCfg 解析路由
      const route = {
        path: routeCfg.path || router.path || routeCfg.router,
        name: routeCfg.name || router.name,
        component: router.component,
        redirect: routeCfg.redirect || router.redirect,
        meta: {
          authority:
            routeCfg.authority ||
            router.authority ||
            routeCfg.meta?.authority ||
            router.meta?.authority ||
            '*',
          icon:
            routeCfg.icon ||
            router.icon ||
            routeCfg.meta?.icon ||
            router.meta?.icon,
          page:
            routeCfg.page ||
            router.page ||
            routeCfg.meta?.page ||
            router.meta?.page,
          link:
            routeCfg.link ||
            router.link ||
            routeCfg.meta?.link ||
            router.meta?.link
        }
      }
      if (routeCfg.invisible || router.invisible) {
        route.meta.invisible = true
      }
      if (routeCfg.children && routeCfg.children.length > 0) {
        route.children = parseRoutes(routeCfg.children, routerMap)
      }
      routes.push(route)
    })
    return routes
  }
  
  /**
   * 加载路由
   * @param routesConfig {RouteConfig[]} 路由配置
   */
  function loadRoutes(routesConfig) {
    //兼容 0.6.1 以下版本
    /*************** 兼容 version < v0.6.1 *****************/
    if (arguments.length > 0) {
      const arg0 = arguments[0]
      if (arg0.router || arg0.i18n || arg0.store) {
        routesConfig = arguments[1]
        console.error(
          'the usage of signature loadRoutes({router, store, i18n}, routesConfig) is out of date, please use the new signature: loadRoutes(routesConfig).'
        )
        console.error(
          '方法签名 loadRoutes({router, store, i18n}, routesConfig) 的用法已过时, 请使用新的方法签名 loadRoutes(routesConfig)。'
        )
      }
    }
    /*************** 兼容 version < v0.6.1 *****************/
  
    // 应用配置
    const { router, store, i18n } = appOptions
  
    // 如果 routesConfig 有值，则更新到本地，否则从本地获取
    if (routesConfig) {
      store.commit('account/setRoutesConfig', routesConfig)
    } else {
      routesConfig = store.getters['account/routesConfig']
    }
    // 如果开启了异步路由，则加载异步路由配置
    const asyncRoutes = store.state.setting.asyncRoutes
    if (asyncRoutes) {
      if (routesConfig && routesConfig.length > 0) {
        const routes = parseRoutes(routesConfig, routerMap)
        const finalRoutes = mergeRoutes(basicOptions.routes, routes)
        formatRoutes(finalRoutes)
        router.options = { ...router.options, routes: finalRoutes }
        router.matcher = new Router({ ...router.options, routes: [] }).matcher
        router.addRoutes(finalRoutes)
      }
    }
    // 提取路由国际化数据
    mergeI18nFromRoutes(i18n, router.options.routes)
    // 初始化Admin后台菜单数据
    const rootRoute = router.options.routes.find(item => item.path === '/')
    const menuRoutes = rootRoute && rootRoute.children
    if (menuRoutes) {
      store.commit('setting/setMenuData', menuRoutes)
    }
  }
  
  /**
   * 合并路由
   * @param target {Route[]}
   * @param source {Route[]}
   * @returns {Route[]}
   */
  function mergeRoutes(target, source) {
    const routesMap = {}
    target.forEach(item => (routesMap[item.path] = item))
    source.forEach(item => (routesMap[item.path] = item))
    return Object.values(routesMap)
  }
  
  /**
   * 深度合并路由
   * @param target {Route[]}
   * @param source {Route[]}
   * @returns {Route[]}
   */
  function deepMergeRoutes(target, source) {
    // 映射路由数组
    const mapRoutes = routes => {
      const routesMap = {}
      routes.forEach(item => {
        routesMap[item.path] = {
          ...item,
          children: item.children ? mapRoutes(item.children) : undefined
        }
      })
      return routesMap
    }
    const tarMap = mapRoutes(target)
    const srcMap = mapRoutes(source)
  
    // 合并路由
    const merge = deepMerge(tarMap, srcMap)
  
    // 转换为 routes 数组
    const parseRoutesMap = routesMap => {
      return Object.values(routesMap).map(item => {
        if (item.children) {
          item.children = parseRoutesMap(item.children)
        } else {
          delete item.children
        }
        return item
      })
    }
    return parseRoutesMap(merge)
  }
  
  /**
   * 格式化路由
   * @param routes 路由配置
   */
  function formatRoutes(routes) {
    routes.forEach(route => {
      const { path } = route
      if (!path.startsWith('/') && path !== '*') {
        route.path = '/' + path
      }
    })
    formatAuthority(routes)
  }
  
  /**
   * 格式化路由的权限配置
   * @param routes 路由
   * @param pAuthorities 父级路由权限配置集合
   */
  function formatAuthority(routes, pAuthorities = []) {
    routes.forEach(route => {
      const meta = route.meta
      const defaultAuthority = pAuthorities[pAuthorities.length - 1] || {
        permission: '*'
      }
      if (meta) {
        let authority = {}
        if (!meta.authority) {
          authority = defaultAuthority
        } else if (typeof meta.authority === 'string') {
          authority.permission = meta.authority
        } else if (typeof meta.authority === 'object') {
          authority = meta.authority
          const { role } = authority
          if (typeof role === 'string') {
            authority.role = [role]
          }
          if (!authority.permission && !authority.role) {
            authority = defaultAuthority
          }
        }
        meta.authority = authority
      } else {
        const authority = defaultAuthority
        route.meta = { authority }
      }
      route.meta.pAuthorities = pAuthorities
      if (route.children) {
        formatAuthority(route.children, [...pAuthorities, route.meta.authority])
      }
    })
  }
  
  /**
   * 从路由 path 解析 i18n key
   * @param path
   * @returns {*}
   */
  function getI18nKey(path) {
    const keys = path
      .split('/')
      .filter(item => !item.startsWith(':') && item != '')
    keys.push('name')
    return keys.join('.')
  }
  
  /**
   * 加载导航守卫
   * @param guards
   * @param options
   */
  function loadGuards(guards, options) {
    const { beforeEach, afterEach } = guards
    const { router } = options
    beforeEach.forEach(guard => {
      if (guard && typeof guard === 'function') {
        router.beforeEach((to, from, next) => guard(to, from, next, options))
      }
    })
    afterEach.forEach(guard => {
      if (guard && typeof guard === 'function') {
        router.afterEach((to, from) => guard(to, from, options))
      }
    })
  }
  
  export {
    parseRoutes,
    loadRoutes,
    formatAuthority,
    getI18nKey,
    loadGuards,
    deepMergeRoutes,
    formatRoutes,
    setAppOptions
  }
  