wsj
3 days ago 71719ffa0eeb4a28a1b736f87499bcda2847a848
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
74
75
76
77
78
79
80
81
82
83
import type { ReactNode } from 'react';
import { Navigate, Outlet, useLocation, useRoutes } from 'react-router-dom';
import type { RouteObject } from 'react-router-dom';
import BasicLayout from '@/layouts/BasicLayout';
import NotFound from '@/pages/error/NotFound';
import Login from '@/pages/login';
import { useAuthStore } from '@/store/auth';
import {
  appRoutes,
  findFirstPath,
  type AppRouteItem,
} from './routeConfig';
 
/** 未登录时跳转登录页,并记录来源地址。 */
const RequireAuth = ({ children }: { children: ReactNode }) => {
  const token = useAuthStore((state) => state.token);
  const location = useLocation();
 
  if (!token) {
    return (
      <Navigate
        to="/login"
        replace
        state={{ from: `${location.pathname}${location.search}` }}
      />
    );
  }
 
  return <>{children}</>;
};
 
/** 分组路由的默认跳转:进入第一个子页面。 */
const GroupIndexRedirect = ({ item }: { item: AppRouteItem }) => {
  const target = findFirstPath(item);
 
  return <Navigate to={target ?? '/dashboard'} replace />;
};
 
/** 把嵌套的菜单配置转换成 react-router 的嵌套路由。 */
const toRouteObjects = (items: AppRouteItem[], parentPath = ''): RouteObject[] =>
  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 ?? <Outlet />,
    };
 
    if (childRoutes.length > 0) {
      route.children = [
        { index: true, element: <GroupIndexRedirect item={item} /> },
        ...childRoutes,
      ];
    }
 
    return route;
  });
 
const routes: RouteObject[] = [
  { path: '/login', element: <Login /> },
  {
    path: '/',
    element: (
      <RequireAuth>
        <BasicLayout />
      </RequireAuth>
    ),
    children: [
      { index: true, element: <Navigate to="/dashboard" replace /> },
      ...toRouteObjects(appRoutes),
      { path: '*', element: <NotFound /> },
    ],
  },
];
 
const AppRouter = () => useRoutes(routes);
 
export default AppRouter;