import { Navigate, Outlet, useRoutes } from 'react-router-dom';
|
import type { RouteObject } from 'react-router-dom';
|
import RouteGuard from '@/components/RouteGuard';
|
import BasicLayout from '@/layouts/BasicLayout';
|
import Forbidden from '@/pages/error/Forbidden';
|
import NotFound from '@/pages/error/NotFound';
|
import Login from '@/pages/login';
|
import { useAuthStore } from '@/store/auth';
|
import {
|
appRoutes,
|
findFirstAccessiblePath,
|
type AppRouteItem,
|
} from './routeConfig';
|
|
/** 分组路由的默认跳转:自动进入第一个有权限的子页面。 */
|
function GroupIndexRedirect({ item }: { item: AppRouteItem }) {
|
const hasPermission = useAuthStore((state) => state.hasPermission);
|
const target = findFirstAccessiblePath(item, hasPermission);
|
|
return <Navigate to={target ?? '/403'} replace />;
|
}
|
|
/** 把嵌套的菜单配置转换成 react-router 的嵌套路由。 */
|
function toRouteObjects(items: AppRouteItem[], parentPath = ''): RouteObject[] {
|
return items.map((item) => {
|
const relativePath =
|
parentPath && item.path.startsWith(parentPath)
|
? item.path.slice(parentPath.length).replace(/^\//, '')
|
: item.path.replace(/^\//, '');
|
|
const childRoutes = item.children ? toRouteObjects(item.children, item.path) : [];
|
|
const route: RouteObject = {
|
path: relativePath,
|
element: item.element ? (
|
<RouteGuard permission={item.permission}>{item.element}</RouteGuard>
|
) : (
|
<Outlet />
|
),
|
};
|
|
if (childRoutes.length > 0) {
|
route.children = [
|
{ index: true, element: <GroupIndexRedirect item={item} /> },
|
...childRoutes,
|
];
|
}
|
|
return route;
|
});
|
}
|
|
const routes: RouteObject[] = [
|
{ path: '/login', element: <Login /> },
|
{ path: '/403', element: <Forbidden /> },
|
{
|
path: '/',
|
element: (
|
<RouteGuard>
|
<BasicLayout />
|
</RouteGuard>
|
),
|
children: [
|
{ index: true, element: <Navigate to="/dashboard" replace /> },
|
...toRouteObjects(appRoutes),
|
{ path: '*', element: <NotFound /> },
|
],
|
},
|
];
|
|
export default function AppRouter() {
|
return useRoutes(routes);
|
}
|