From d18a4b98f4e0faf95ca344771ccfa2e66d35b531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=87=91?= Date: Sun, 28 Apr 2024 18:30:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=B7=AF=E7=94=B1=E4=B8=BA?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E3=80=82=E5=BE=85=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 8 ++- src/pages/dashboard/index.tsx | 32 +++++------ src/routes.tsx | 129 ++++++++++++++++++++++++------------------ src/service/system.ts | 3 +- src/store/user.ts | 8 +-- 5 files changed, 102 insertions(+), 78 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index fd2cbbb..5a9062b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ - import { AppContextProvider } from '@/context.ts' +import { AppContextProvider } from '@/context.ts' import { initI18n } from '@/i18n.ts' import { appAtom, appStore, changeLanguage } from '@/store/system.ts' import { userMenuDataAtom } from '@/store/user.ts' @@ -14,7 +14,7 @@ import PageLoading from '@/components/page-loading' function App() { const [ appData, ] = useAtom(appAtom) - const { data = [], isLoading, refetch } = useAtomValue(userMenuDataAtom) + const { data = [], isLoading, isFetching, refetch } = useAtomValue(userMenuDataAtom) useEffect(() => { initI18n() @@ -28,10 +28,12 @@ function App() { }, [ appData.token ]) - if (isLoading) { + if (isLoading || isFetching) { return } + console.log('app render', data) + return ( { - return ( - <> - + return ( + <> + -

Dashboard

+

Dashboard

-
- - ) +
+ + ) } -export const Route = createFileRoute('/dashboard')({ - component: Index, +export const Route = createLazyFileRoute('/dashboard')({ + component: Index, }) export default Index \ No newline at end of file diff --git a/src/routes.tsx b/src/routes.tsx index 3e3c4f8..fd2e428 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -8,6 +8,7 @@ import EmptyLayout from '@/layout/EmptyLayout.tsx' import ListPageLayout from '@/layout/ListPageLayout.tsx' import { Route as DashboardImport } from '@/pages/dashboard' import { Route as LoginRouteImport } from '@/pages/login' +import { generateUUID } from '@/utils/uuid.ts' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { AnyRoute, @@ -85,10 +86,10 @@ const notAuthRoute = createRoute({ component: NotPermission }) -const dashboardRoute = DashboardImport.update({ - path: '/dashboard', - getParentRoute: () => layoutAuthRoute, -} as any) +// const dashboardRoute = DashboardImport.update({ +// path: '/dashboard', +// getParentRoute: () => layoutAuthRoute, +// } as any) const loginRoute = LoginRouteImport.update({ path: '/login', @@ -165,50 +166,21 @@ declare module '@tanstack/react-router' { } } - -const routeTree = rootRoute.addChildren( - [ - //非Layout - loginRoute, - emptyRoute, - - //不带权限Layout - layoutNormalRoute.addChildren([ - notAuthRoute, - ]), - - //带权限Layout - dashboardRoute, - authRoute.addChildren( - [ - layoutAuthRoute.addChildren( - [ - menusRoute, - departmentsRoute, - usersRoute, - rolesRoute, - ] - ), - ] - ) - ] -) - - -export const generateDynamicRoutes = (menuData: MenuItem[]) => { +export const generateDynamicRoutes = (menuData: MenuItem[], parentRoute: AnyRoute) => { // 递归生成路由,如果有routes则递归生成子路由 const generateRoutes = (menu: MenuItem, parentRoute: AnyRoute) => { - + console.log('gen route', menu) const path = menu.path?.replace(parentRoute.options?.path, '') const isLayout = menu.children && menu.children.length > 0 && menu.type === 'menu' - if (isLayout && !menu.component) { + if (isLayout && (!menu.path || !menu.component)) { //没有component的layout,直接返回 + console.log('no-page') return createRoute({ - getParentRoute: () => parentRoute, - id: path!, - component: ListPageLayout, + getParentRoute: () => layoutAuthRoute, + id: `/layout-no-path-${generateUUID()}`, + component: RootLayout, }) } @@ -219,11 +191,17 @@ export const generateDynamicRoutes = (menuData: MenuItem[]) => { } as any if (isLayout) { - options.id = path! + options.id = path ?? `/layout-${generateUUID()}` } else { - options.path = path! + if (!path) { + console.log(`${menu.name}没有设置视图`) + } else { + options.path = path + } } + console.log('gen route', options) + //删除掉parentRoute的path,避免重复 const route = createRoute(options).lazy(async () => { @@ -238,52 +216,95 @@ export const generateDynamicRoutes = (menuData: MenuItem[]) => { } if (!component) { - return createLazyRoute(menu.path)({ + return createLazyRoute(options.path)({ component: () =>
404 Not Found
}) } + + //处理component路径 + component = component.replace(/^\/pages/, '') + component = component.replace(/^\//, '') + + console.log('load', `/pages/${component}`) /* @vite-ignore */ - const d = await import(`${component}`) + const d = await import(`/pages/${component}`) if (d.Route) { + console.log(d.Route) return d.Route } if (d.GenRoute) { - return d.GenRoute(menu.path) + return d.GenRoute(options.path) } - return createLazyRoute(menu.path)({ + return createLazyRoute(options.path)({ component: d.default || d }) }) - return route + return route } // 对menuData递归生成路由,只处理type =1 的菜单 const did = (menus: MenuItem[], parentRoute: AnyRoute) => { - return menus.filter((item) => item.type === 'menu').map((item) => { + return menus.filter((item) => item.type === 'menu').map((item, index) => { // 如果有children则递归生成子路由,同样只处理type =1 的菜单 const route = generateRoutes(item, parentRoute) + + // console.log(route) if (item.children && item.children.length > 0) { const children = did(item.children, route) if (children.length > 0) { route.addChildren(children) } } + route.init({ originalIndex: index }) return route }) } - return did(menuData, rootRoute) + const routes = did(menuData, parentRoute) + + parentRoute.addChildren(routes) + } +const routeTree = rootRoute.addChildren( + [ + //非Layout + loginRoute, + emptyRoute, + + //不带权限Layout + layoutNormalRoute.addChildren([ + notAuthRoute, + ]), + + //带权限Layout + // dashboardRoute, + authRoute.addChildren( + [ + layoutAuthRoute + /*.addChildren( + [ + menusRoute, + departmentsRoute, + usersRoute, + rolesRoute, + ] + ),*/ + ]), + ] +) -const router = createRouter({ - routeTree, - context: { queryClient, menuData: [] }, - defaultPreload: 'intent' -}) export const RootProvider = memo((props: { context: Partial }) => { + generateDynamicRoutes(props.context.menuData ?? [], layoutAuthRoute) + + const router = createRouter({ + routeTree, + context: { queryClient, menuData: [] }, + defaultPreload: 'intent' + }) + return ( diff --git a/src/service/system.ts b/src/service/system.ts index 44cb5c8..49061dc 100644 --- a/src/service/system.ts +++ b/src/service/system.ts @@ -1,3 +1,4 @@ +import { IPageResult } from '@/types' import { IUserInfo } from '@/types/user' import request from '../request.ts' import { LoginRequest, LoginResponse } from '@/types/login' @@ -20,7 +21,7 @@ const systemServ = { return request.get('/sys/user/info') }, menus: () => { - return request.get('/sys/user/menus') + return request.get>('/sys/user/menus') } }, diff --git a/src/store/user.ts b/src/store/user.ts index a6648ad..10b726e 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -1,8 +1,8 @@ import { appAtom } from '@/store/system.ts' +import { IMenu } from '@/types/menus' import { IUserInfo } from '@/types/user' -import { AxiosResponse } from 'axios' import { atom } from 'jotai/index' -import { IApiResult, IAuth, MenuItem } from '@/types' +import { IApiResult, IAuth, IPageResult, MenuItem } from '@/types' import { LoginRequest } from '@/types/login' import { atomWithMutation, atomWithQuery } from 'jotai-tanstack-query' import systemServ from '@/service/system.ts' @@ -45,13 +45,13 @@ export const currentUserAtom = atomWithQuery, any, IUserIn } }) -export const userMenuDataAtom = atomWithQuery((get) => ({ +export const userMenuDataAtom = atomWithQuery>, any, MenuItem[]>((get) => ({ enabled: false, queryKey: [ 'user_menus', get(appAtom).token ], queryFn: async () => { return await systemServ.user.menus() }, - select: (data: AxiosResponse) => { + select: (data) => { return formatMenuData(data.data.rows as any ?? []) }, cacheTime: 1000 * 60,