wsj
2026-10-17 5630cce7759c27d910fbeeec370a2e9f6b4b26b1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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);
}