import settings from '../config/settings' ; import { isExternal } from './validate' ; /**
 * 路由类型
 */ export interface RoutesDataItem { hidden ? : boolean ; icon ? : string ; roles ? : string [ ] ; title : string ; path : string ; redirect ? : string ; component ? : string ; routes ? : RoutesDataItem [ ] ; /**
     * 面包屑自定义内容：
     *     1、默认不配置按照路由自动读取；
     *     2、设置为 false , 按照路由自动读取并不读当前自己；
     *     3、配置对应的面包屑格式如下：
     */ breadcrumb ? : RoutesDataItem [ ] | false ; /**
     * 左侧菜单选中，如果设置路径，侧栏将突出显示你设置的路径对应的侧栏导航
     *   1、（默认 route.path），此参数是为了满足特殊页面特殊需求，
     *   2、如：详情页等选中侧栏导航或在模块A下面的页面，想选模块B为导航选中状态
     */ selectLeftMenu ? : string ; /**
     * 所属顶级菜单,当顶级菜单存在时，用于选中顶部菜单，与侧栏菜单切换
     *   1、三级路由此参数的作用是选中顶级菜单
     *   2、二级路由此参数的作用是所属某个顶级菜单的下面，两个层级的必须同时填写一致，如果path设置的是外链，此参数必填
     *   3、(默认不设置 path.split('/')[0])，此参数是为了满足特殊页面特殊需求
     */ belongTopMenu ? : string ; } param pathname param routesData export const getRouteItem = ( pathname , routesData ) : RoutesDataItem => { let item = { title : '' , path : '' } ; for ( let index = 0 , len = routesData . length ; index < len ; index += 1 ) { const element = routesData [ index ] ; if ( element . path === pathname ) { item = element ; break ; } if ( element . routes ) { item = getRouteItem ( pathname , element . routes ) ; if ( item . path !== '' ) { break ; } } } return item ; } ; param pathname param routesData export const getRouteParentItem = ( pathname , routesData , defaultParentItem ) : Partial < RoutesDataItem > => { let item = { } ; for ( let index = 0 , len = routesData . length ; index < len ; index += 1 ) { const element = routesData [ index ] ; if ( element . path === pathname ) { item = defaultParentItem ; break ; } if ( element . routes ) { item = getRouteParentItem ( pathname , element . routes , element ) ; if ( Object . keys ( item ) . length ) { break ; } } } return item ; } ; param pathname param separator export const formatRoutePathTheParents = ( pathname , separator = '/' ) : string [ ] => { const arr = [ ] ; if ( ! pathname || pathname === '' ) { return arr ; } const pathArr = pathname . split ( separator ) ; for ( let index = 1 , len = pathArr . length - 1 ; index < len ; index += 1 ) { arr . push ( pathArr . slice ( 0 , index + 1 ) . join ( separator ) ) ; } return arr ; } ; param pathname param routesData export const getPathsTheRoutes = ( pathname , routesData ) : RoutesDataItem [ ] => { const routeItem = [ ] ; for ( let index = 0 , len = pathname . length ; index < len ; index += 1 ) { const element = pathname [ index ] ; const item = getRouteItem ( element , routesData ) ; if ( item . path !== '' ) { routeItem . push ( item ) ; } } return routeItem ; } ; param route param pathname param routesData export const getBreadcrumbRoutes = ( route , pathname , routesData , formatMessage ? ) : RoutesDataItem [ ] => { if ( ! route . breadcrumb ) { const routePaths = getPathsTheRoutes ( pathname , routesData ) ; return route . breadcrumb === false ? routePaths : [ ... routePaths , route ] ; } if ( formatMessage ) { if ( route [ 'breadcrumbFormatMessage' ] === true ) { return route . breadcrumb ; } else { route [ 'breadcrumbFormatMessage' ] = true ; return route . breadcrumb . map ( item => { item . title = formatMessage ( { id : item . title } ) as string ; return item ; } ) ; } } return route . breadcrumb ; } ; param route export const getSelectLeftMenuPath = ( route ) : string => { return route . selectLeftMenu || route . path ; } ; param route export const getRouteBelongTopMenu = ( route ) : string => { if ( route . belongTopMenu ) { return route . belongTopMenu ; } return `/${ route . path . split ( '/' ) [ 1 ] }` ; } ; param pathname param routes export const getRouteBelongTopMenuForRoutes = ( pathname , routes ) : string => { const routeItem = getRouteItem ( pathname , routes ) ; return getRouteBelongTopMenu ( routeItem ) ; } ; param pathname param parentPath param headStart export const setRoutePathForParent = ( pathname , parentPath = '/' , headStart = '/' ) : string => { if ( isExternal ( pathname ) ) { return pathname ; } return pathname . substr ( 0 , headStart . length ) === headStart ? pathname : `${ parentPath }/${ pathname }` ; } ; /**
 * 返回404路由
 */ export const getNotFoundRoute = ( ) : RoutesDataItem => { return { hidden : true , title : '' , path : '*' , component : settings . notFoundComponent , } ; } ; param routesData param parentPath param headStart export const umiRoutes = ( routesData , parentPath = '/' , headStart = '/' ) : RoutesDataItem [ ] => { return routesData . map ( item => { const { redirect , routes , ... other } = item ; const itemRoutes = routes || [ ] ; const newItem = { ... other } ; newItem . path = setRoutePathForParent ( newItem . path , parentPath , headStart ) ; /**
         * 处理跳转[redirect]
         * 因为 react 路由 如果父级有 redirect 后，子集路由不再好使
         * 这里把处理成有效
         */ if ( item . redirect && item . routes ) { newItem . routes = [ ... umiRoutes ( itemRoutes , newItem . path , headStart ) , { hidden : true , title : newItem . title , path : newItem . path , redirect : item . redirect , } , getNotFoundRoute ( ) , ] ; } else if ( item . redirect && ! item . routes ) { newItem . redirect = redirect ; } else if ( ! item . redirect && item . routes ) { newItem . routes = [ ... umiRoutes ( itemRoutes , newItem . path , headStart ) , getNotFoundRoute ( ) , ] ; } return newItem ; } ) ; } ; param userRoles param role export const hasPermissionRouteRoles = ( userRoles , role ) : boolean => { if ( userRoles . includes ( 'admin' ) ) { return true ; } return userRoles . includes ( role ) ; } ; param roles param route export const hasPermission = ( roles , route ) : boolean => { if ( roles . includes ( 'admin' ) ) { return true ; } if ( route . roles ) { return route . roles . some ( role => roles . includes ( role ) ) ; } return true ; } ; param roles param routes export const getPermissionMenuData = ( roles , routes ) : RoutesDataItem [ ] => { const menu = [ ] ; for ( let index = 0 , len = routes . length ; index < len ; index += 1 ) { const element = routes [ index ] ; if ( hasPermission ( roles , element ) ) { if ( element . routes ) { element . routes = getPermissionMenuData ( roles , element . routes ) ; } menu . push ( element ) ; } } return menu ; } ;