Skip to content

Commit

Permalink
feat: route without auth redirect to 404
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuhengtan committed May 13, 2023
1 parent 663a153 commit e41c300
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 214 deletions.
27 changes: 9 additions & 18 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
import './lang/i18n'

import React from 'react'
import { useLocalStorageState } from 'ahooks'
import { ConfigProvider } from 'antd'
import React, { useEffect } from 'react'
import {
BrowserRouter as Router, useRoutes, useParams, RouteObject,
} from 'react-router-dom'
import routes from '@/routes'
import theme from './antd-theme.json'
import { languageMap } from './utils'
ConfigProvider,
} from 'antd'

function GetRoutes() {
const elements = useRoutes(routes as RouteObject[])
import useGetAuthRoutes from '@/routes/auth-routes'

return elements
}
import theme from './antd-theme.json'
import { languageMap } from './utils'

function App() {
const [language] = useLocalStorageState('LANGUAGE', {
defaultValue: 'zh',
})
const [token] = useLocalStorageState('TOKEN', {
defaultValue: '',
})

const { authRoutes } = useGetAuthRoutes()

return (
// 默认使用中文包,需要切换国际化时请自行配置
<ConfigProvider locale={(languageMap as any)[language as string].antd} theme={theme}>
<Router>
<GetRoutes />
</Router>
{authRoutes}
</ConfigProvider>
)
}
Expand Down
252 changes: 57 additions & 195 deletions src/components/layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-continue */
import './index.less'
import 'antd/es/layout/style'

Expand All @@ -8,7 +7,6 @@ import { useLocalStorageState, useRequest } from 'ahooks'
import {
Breadcrumb,
Layout, Menu,
MenuProps,
Space,
} from 'antd'
import React, {
Expand All @@ -22,15 +20,14 @@ import { Outlet, Link } from 'react-router-dom'
import allRoutes from '@/routes'

import api from '@/service'
import { AdminAuthContext } from '@/context/AdminAuthContext'
import { AdminInfo, CustomRouteObject } from '@/type'

import { CustomRouteObject } from '@/type'

import useGetAuthRoutes from '@/routes/auth-routes'
import Avatar from './avatar'
import GlobalLan from './global-lan'
import Logo from './logo'

const { getAdminAuth: getAdminAuthRequest } = api

interface BreadcrumbItem {
path: string
name: string
Expand All @@ -44,9 +41,6 @@ const CustomLayout = () => {
const navigate = useNavigate()
const [collapsed, setCollapsed] = useState(false)
const { t } = useTranslation()
const [adminAuth, setAdminAuth] = useState({})
const [finalAuth, setAuth] = useLocalStorageState('AUTH', {})
const [admin] = useLocalStorageState('USER_INFO')

// 如果没有登录,跳转登录页
const [token] = useLocalStorageState('TOKEN', {
Expand Down Expand Up @@ -121,195 +115,63 @@ const CustomLayout = () => {
setCollapsed(!collapsed)
}, [collapsed])

const goToPage = useCallback(
(menu: CustomRouteObject) => {
// const path = menu.path.toLocaleString();
navigate(menu.path as any)
},
[navigate],
)

function renderMenuItem(originRoutes: CustomRouteObject[]) {
return originRoutes
.filter((item) => !item.hidden)
.map((item) => {
const { path, icon, name } = item
const routes = (item.children || []).filter((item2) => !item2.hidden)
if (routes.length) {
return (
<SubMenu key={path as string} icon={icon} title={name}>
{renderMenuItem(routes)}
</SubMenu>
)
}
return (
<Menu.Item
key={path as string}
onClick={() => {
goToPage(item)
}}
title={name}
icon={icon}
>
{name}
</Menu.Item>
)
})
}

const { run: getAdminAuth } = useRequest(() => getAdminAuthRequest({ id: (admin as AdminInfo).id }), {
manual: true,
onSuccess(e: any) {
setAdminAuth(e.auth)
setAuth(e.auth)
},
})

useEffect(() => {
if (token) {
getAdminAuth()
}
}, [getAdminAuth, token])

// const filterRoutersByPermission = useCallback(
// (routers: RouteConfig[]) => {
// const arr: RouteConfig[] = []
// routers.some((router) => {
// const obj = { ...router }
// if (
// obj.checkAuth
// && Object.prototype.hasOwnProperty.call(adminAuth, obj.path as string)
// ) {
// arr.push(obj)
// }
// if (obj.routes && obj.routes.length) {
// const newRouters = filterRoutersByPermission(obj.routes)
// if (newRouters.length) {
// obj.routes = newRouters
// arr.push(obj)
// return true
// }
// return true
// }
// if (!obj.checkAuth) {
// arr.push(obj)
// }
// return false
// })
// return arr
// },
// [adminAuth],
// )

const routeItemsWithPermission = useMemo(() => {
const filterRoutersByPermission = (routers: CustomRouteObject[]): MenuProps['items'] => {
const arr: MenuProps['items'] = []
for (let i = 0; i < routers.length; i++) {
const obj = { ...routers[i] }
if (obj.hidden) {
continue
}
if (obj.checkAuth) {
if (Object.hasOwn(adminAuth, obj.path as string)) {
arr.push({
key: obj.path as string,
icon: obj.icon,
title: obj.name,
label: obj.name,
onClick: () => {
goToPage(obj)
},
})
continue
}
continue
}
if (obj.children && obj.children.length) {
const newRouters = filterRoutersByPermission(obj.children)
if (newRouters && newRouters.length) {
arr.push({
key: obj.path as string,
icon: obj.icon,
title: obj.name,
label: obj.name,
children: newRouters,
})
continue
}
continue
}
arr.push({
key: obj.path as string,
icon: obj.icon,
title: obj.name,
label: obj.name,
onClick: () => {
goToPage(obj)
},
})
}
return arr
}
return filterRoutersByPermission(allRoutes)
}, [goToPage, adminAuth])
const { menuList } = useGetAuthRoutes()

return (
<AdminAuthContext.Provider value={finalAuth as any}>
<Layout className="layout-container">
<Sider
width={200}
trigger={null}
collapsible
collapsed={collapsed}
className="side-bar"
>
<Logo collapsed={collapsed} />
<Menu
mode="inline"
defaultSelectedKeys={defaultSelectedKeys}
defaultOpenKeys={defaultOpenKeys}
selectedKeys={defaultSelectedKeys}
items={routeItemsWithPermission}
/>
</Sider>
<Layout className="right-container">
<Header className="header">
<div className="left">
{React.createElement(
collapsed ? MenuUnfoldOutlined : MenuFoldOutlined,
{
onClick: toggleCollapse,
},
)}
<Breadcrumb className="breadcrumb">
{breadcrumbList.map((item: BreadcrumbItem) => {
if (typeof item === 'object') {
return (
<Breadcrumb.Item key={item.key}>
{item.path ? (
<Link to={item.path}>{t(item.name)}</Link>
) : (
t(item.name)
)}
</Breadcrumb.Item>
)
}
return <Breadcrumb.Item key={item}>{item}</Breadcrumb.Item>
})}
</Breadcrumb>
</div>
<Space direction="horizontal" align="center">
<GlobalLan />
<Avatar />
</Space>
</Header>
<Content className="content">
<Outlet />
</Content>
<div className="footer">{t('APP NAME')}</div>
</Layout>
<Layout className="layout-container">
<Sider
width={200}
trigger={null}
collapsible
collapsed={collapsed}
className="side-bar"
>
<Logo collapsed={collapsed} />
<Menu
mode="inline"
defaultSelectedKeys={defaultSelectedKeys}
defaultOpenKeys={defaultOpenKeys}
selectedKeys={defaultSelectedKeys}
items={menuList}
/>
</Sider>
<Layout className="right-container">
<Header className="header">
<div className="left">
{React.createElement(
collapsed ? MenuUnfoldOutlined : MenuFoldOutlined,
{
onClick: toggleCollapse,
},
)}
<Breadcrumb className="breadcrumb">
{breadcrumbList.map((item: BreadcrumbItem) => {
if (typeof item === 'object') {
return (
<Breadcrumb.Item key={item.key}>
{item.path ? (
<Link to={item.path}>{t(item.name)}</Link>
) : (
t(item.name)
)}
</Breadcrumb.Item>
)
}
return <Breadcrumb.Item key={item}>{item}</Breadcrumb.Item>
})}
</Breadcrumb>
</div>
<Space direction="horizontal" align="center">
<GlobalLan />
<Avatar />
</Space>
</Header>
<Content className="content">
<Outlet />
</Content>
<div className="footer">{t('APP NAME')}</div>
</Layout>
</AdminAuthContext.Provider>
</Layout>
)
}
export default React.memo(CustomLayout)
7 changes: 6 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React from 'react'
import './index.less'
import { createRoot } from 'react-dom/client'
import { BrowserRouter as Router } from 'react-router-dom'

import App from './app'

const container = document.getElementById('root')
const root = createRoot(container!) // createRoot(container!) if you use TypeScript
root.render(<App />)
root.render(
<Router>
<App />
</Router>,
)
Loading

0 comments on commit e41c300

Please sign in to comment.