Complete main UI #37
22
src/App.tsx
22
src/App.tsx
@@ -1,13 +1,27 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import router from '@/router'
|
import { getRouter } from '@/router'
|
||||||
import LoadingMask from '@/components/common/LoadingMask'
|
import LoadingMask from '@/components/common/LoadingMask'
|
||||||
|
|
||||||
|
export const AppContext = createContext<{ refreshRouter: () => void }>({
|
||||||
|
refreshRouter: () => undefined
|
||||||
|
})
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
|
const [routerState, setRouterState] = useState(getRouter)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Suspense fallback={<LoadingMask />}>
|
<AppContext.Provider
|
||||||
<RouterProvider router={router} />
|
value={{
|
||||||
</Suspense>
|
refreshRouter: () => {
|
||||||
|
setRouterState(getRouter())
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Suspense fallback={<LoadingMask />}>
|
||||||
|
<RouterProvider router={routerState} />
|
||||||
|
</Suspense>
|
||||||
|
</AppContext.Provider>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,13 @@ const AuthRoute = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (isLogin && lastMatch.pathname === '/login') {
|
if (isLogin && lastMatch.pathname === '/login') {
|
||||||
return <Navigate to="/" />
|
return <Navigate to={'/'} />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (location.pathname.length > 1 && location.pathname.endsWith('/')) {
|
||||||
|
return <Navigate to={location.pathname.substring(0, location.pathname.length - 1)} />
|
||||||
|
}
|
||||||
|
|
||||||
return outlet
|
return outlet
|
||||||
}, [
|
}, [
|
||||||
handle?.title,
|
handle?.title,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import Icon from '@ant-design/icons'
|
import Icon from '@ant-design/icons'
|
||||||
import '@/assets/css/pages/home-framework.scss'
|
import '@/assets/css/pages/home-framework.scss'
|
||||||
import { COLOR_FONT_SECONDARY } from '@/constants/common.constants'
|
import { COLOR_FONT_SECONDARY } from '@/constants/common.constants'
|
||||||
import router from '@/router'
|
import { getRouter } from '@/router'
|
||||||
import LoadingMask from '@/components/common/LoadingMask'
|
import LoadingMask from '@/components/common/LoadingMask'
|
||||||
import HideScrollbar, { HideScrollbarElement } from '@/components/common/HideScrollbar'
|
import HideScrollbar, { HideScrollbarElement } from '@/components/common/HideScrollbar'
|
||||||
|
|
||||||
@@ -54,7 +54,8 @@ export const HomeFrameworkContext = createContext<{
|
|||||||
|
|
||||||
const HomeFramework: React.FC = () => {
|
const HomeFramework: React.FC = () => {
|
||||||
const routeId = useMatches()[1].id
|
const routeId = useMatches()[1].id
|
||||||
const routeChildren = router.routes[0].children?.find((value) => value.id === routeId)?.children
|
const routeChildren = getRouter().routes[0].children?.find((value) => value.id === routeId)
|
||||||
|
?.children
|
||||||
|
|
||||||
const pathname = useLocation().pathname
|
const pathname = useLocation().pathname
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import {
|
|||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
import { utcToLocalTime } from '@/util/datetime'
|
import { utcToLocalTime } from '@/util/datetime'
|
||||||
import { getUserInfo, login, setToken } from '@/util/auth'
|
import { getUserInfo, login, setToken } from '@/util/auth'
|
||||||
|
import { AppContext } from '@/App'
|
||||||
|
|
||||||
const Login: React.FC = () => {
|
const Login: React.FC = () => {
|
||||||
|
const { refreshRouter } = useContext(AppContext)
|
||||||
const [messageApi, contextHolder] = message.useMessage()
|
const [messageApi, contextHolder] = message.useMessage()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [searchParams] = useSearchParams()
|
const [searchParams] = useSearchParams()
|
||||||
@@ -32,6 +34,7 @@ const Login: React.FC = () => {
|
|||||||
navigate('/')
|
navigate('/')
|
||||||
}
|
}
|
||||||
void getUserInfo().then((user) => {
|
void getUserInfo().then((user) => {
|
||||||
|
refreshRouter()
|
||||||
notification.success({
|
notification.success({
|
||||||
message: '欢迎回来',
|
message: '欢迎回来',
|
||||||
description: (
|
description: (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import '@/assets/css/pages/system-framework.scss'
|
import '@/assets/css/pages/system-framework.scss'
|
||||||
import system from '@/router/system'
|
import { getSystemRouteJson } from '@/router/system'
|
||||||
import FitFullScreen from '@/components/common/FitFullScreen'
|
import FitFullScreen from '@/components/common/FitFullScreen'
|
||||||
import Sidebar from '@/components/common/sidebar'
|
import Sidebar from '@/components/common/sidebar'
|
||||||
import SidebarItemList from '@/components/common/sidebar/SidebarItemList'
|
import SidebarItemList from '@/components/common/sidebar/SidebarItemList'
|
||||||
@@ -25,7 +25,7 @@ const SystemFramework: React.FC = () => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SidebarItemList>
|
<SidebarItemList>
|
||||||
{system.map((value) => {
|
{getSystemRouteJson().map((value) => {
|
||||||
return value.menu ? (
|
return value.menu ? (
|
||||||
<SidebarItem
|
<SidebarItem
|
||||||
end={value.id === 'system' ? true : undefined}
|
end={value.id === 'system' ? true : undefined}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import '@/assets/css/pages/tools-framework.scss'
|
import '@/assets/css/pages/tools-framework.scss'
|
||||||
import user from '@/router/user'
|
import user from '@/router/user'
|
||||||
import { hasPathPermission } from '@/util/auth'
|
import { hasPathPermission } from '@/util/route'
|
||||||
import FitFullScreen from '@/components/common/FitFullScreen'
|
import FitFullScreen from '@/components/common/FitFullScreen'
|
||||||
import Sidebar from '@/components/common/sidebar'
|
import Sidebar from '@/components/common/sidebar'
|
||||||
import SidebarItemList from '@/components/common/sidebar/SidebarItemList'
|
import SidebarItemList from '@/components/common/sidebar/SidebarItemList'
|
||||||
|
|||||||
@@ -1,41 +1,10 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import _ from 'lodash'
|
||||||
import system from '@/router/system'
|
import system from '@/router/system'
|
||||||
import home from '@/router/home'
|
import home from '@/router/home'
|
||||||
import user from '@/router/user'
|
import user from '@/router/user'
|
||||||
import tools from '@/router/tools'
|
import tools from '@/router/tools'
|
||||||
|
import { getAuthRoute, mapJsonToRoute, setTitle } from '@/util/route'
|
||||||
const mapJsonToRoute = (jsonObject: RouteJsonObject[]): RouteObject[] => {
|
|
||||||
return jsonObject.map((value) => ({
|
|
||||||
path: value.path,
|
|
||||||
id: value.id,
|
|
||||||
element: value.element,
|
|
||||||
Component: value.component,
|
|
||||||
handle: {
|
|
||||||
absolutePath: value.absolutePath,
|
|
||||||
name: value.name,
|
|
||||||
titlePrefix: value.titlePrefix,
|
|
||||||
title: value.title,
|
|
||||||
titlePostfix: value.titlePostfix,
|
|
||||||
icon: value.icon,
|
|
||||||
menu: value.menu,
|
|
||||||
auth: value.auth,
|
|
||||||
permission: value.permission,
|
|
||||||
autoHide: value.autoHide
|
|
||||||
},
|
|
||||||
children: value.children && mapJsonToRoute(value.children)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const setTitle = (jsonObject: RouteJsonObject[], title: string): RouteJsonObject[] => {
|
|
||||||
return jsonObject.map((value) => {
|
|
||||||
if (!value.title) {
|
|
||||||
value.title = title
|
|
||||||
}
|
|
||||||
value.children && setTitle(value.children, title)
|
|
||||||
|
|
||||||
return value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const root: RouteJsonObject[] = [
|
const root: RouteJsonObject[] = [
|
||||||
{
|
{
|
||||||
@@ -80,7 +49,8 @@ const root: RouteJsonObject[] = [
|
|||||||
component: React.lazy(() => import('@/pages/SystemFramework')),
|
component: React.lazy(() => import('@/pages/SystemFramework')),
|
||||||
children: setTitle(system, '系统设置'),
|
children: setTitle(system, '系统设置'),
|
||||||
name: '系统设置',
|
name: '系统设置',
|
||||||
auth: true
|
auth: true,
|
||||||
|
permission: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
@@ -98,7 +68,4 @@ const root: RouteJsonObject[] = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const routes = mapJsonToRoute(root)
|
export const getRouter = () => createBrowserRouter(mapJsonToRoute(getAuthRoute(_.cloneDeep(root))))
|
||||||
|
|
||||||
const router = createBrowserRouter(routes)
|
|
||||||
export default router
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { getAuthRoute } from '@/util/route'
|
||||||
|
|
||||||
const system: RouteJsonObject[] = [
|
const system: RouteJsonObject[] = [
|
||||||
{
|
{
|
||||||
@@ -18,7 +19,6 @@ const system: RouteJsonObject[] = [
|
|||||||
name: '用户管理',
|
name: '用户管理',
|
||||||
icon: React.lazy(() => import('~icons/fatweb/user.jsx')),
|
icon: React.lazy(() => import('~icons/fatweb/user.jsx')),
|
||||||
menu: true,
|
menu: true,
|
||||||
permission: true,
|
|
||||||
autoHide: true
|
autoHide: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,6 @@ const system: RouteJsonObject[] = [
|
|||||||
name: '角色管理',
|
name: '角色管理',
|
||||||
icon: React.lazy(() => import('~icons/fatweb/role.jsx')),
|
icon: React.lazy(() => import('~icons/fatweb/role.jsx')),
|
||||||
menu: true,
|
menu: true,
|
||||||
permission: true,
|
|
||||||
autoHide: true
|
autoHide: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -40,7 +39,6 @@ const system: RouteJsonObject[] = [
|
|||||||
name: '群组管理',
|
name: '群组管理',
|
||||||
icon: React.lazy(() => import('~icons/fatweb/group.jsx')),
|
icon: React.lazy(() => import('~icons/fatweb/group.jsx')),
|
||||||
menu: true,
|
menu: true,
|
||||||
permission: true,
|
|
||||||
autoHide: true
|
autoHide: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -51,7 +49,6 @@ const system: RouteJsonObject[] = [
|
|||||||
name: '系统日志',
|
name: '系统日志',
|
||||||
icon: React.lazy(() => import('~icons/fatweb/log.jsx')),
|
icon: React.lazy(() => import('~icons/fatweb/log.jsx')),
|
||||||
menu: true,
|
menu: true,
|
||||||
permission: true,
|
|
||||||
autoHide: true
|
autoHide: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -61,4 +58,6 @@ const system: RouteJsonObject[] = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const getSystemRouteJson = () => getAuthRoute(system, true)
|
||||||
|
|
||||||
export default system
|
export default system
|
||||||
|
|||||||
@@ -121,39 +121,6 @@ export const getUsername = async () => {
|
|||||||
return user.username
|
return user.username
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getPermissionPath = (): string[] => {
|
|
||||||
const s = getLocalStorage(STORAGE_USER_INFO_KEY)
|
|
||||||
if (s === null) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = JSON.parse(s) as UserWithPowerInfoVo
|
|
||||||
const paths: string[] = []
|
|
||||||
user.menus.forEach((menu) => {
|
|
||||||
paths.push(menu.url)
|
|
||||||
})
|
|
||||||
|
|
||||||
return paths
|
|
||||||
}
|
|
||||||
|
|
||||||
export const hasPathPermission = (path: string) => {
|
|
||||||
return getPermissionPath().indexOf(path) !== -1
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
export const getAuthRoute = (route: RouteJsonObject[]): RouteJsonObject[] => {
|
|
||||||
return route.map((value) => {
|
|
||||||
if (value.absolutePath) {
|
|
||||||
value.absolutePath
|
|
||||||
}
|
|
||||||
if (value.children) {
|
|
||||||
value.children = getAuthRoute(value.children)
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const getCaptchaSrc = () => {
|
export const getCaptchaSrc = () => {
|
||||||
captcha = getCaptcha(300, 150, 4)
|
captcha = getCaptcha(300, 150, 4)
|
||||||
return captcha.base64Src
|
return captcha.base64Src
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import { getLocalStorage } from '@/util/browser.tsx'
|
||||||
|
import { STORAGE_USER_INFO_KEY } from '@/constants/common.constants.ts'
|
||||||
|
|
||||||
export const getRedirectUrl = (path: string, redirectUrl: string): string => {
|
export const getRedirectUrl = (path: string, redirectUrl: string): string => {
|
||||||
return `${path}?redirect=${encodeURIComponent(redirectUrl)}`
|
return `${path}?redirect=${encodeURIComponent(redirectUrl)}`
|
||||||
}
|
}
|
||||||
@@ -11,3 +14,72 @@ export const getFullTitle = (data: _DataNode, preTitle?: string) => {
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getPermissionPath = (): string[] => {
|
||||||
|
const s = getLocalStorage(STORAGE_USER_INFO_KEY)
|
||||||
|
if (s === null) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = JSON.parse(s) as UserWithPowerInfoVo
|
||||||
|
const paths: string[] = []
|
||||||
|
user.menus.forEach((menu) => {
|
||||||
|
paths.push(menu.url)
|
||||||
|
})
|
||||||
|
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
|
export const hasPathPermission = (path: string) => {
|
||||||
|
return getPermissionPath().indexOf(path) !== -1
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getAuthRoute = (
|
||||||
|
route: RouteJsonObject[],
|
||||||
|
parentPermission: boolean = false
|
||||||
|
): RouteJsonObject[] => {
|
||||||
|
return route
|
||||||
|
.filter(
|
||||||
|
(value) =>
|
||||||
|
!(value.permission || parentPermission) || hasPathPermission(value.absolutePath)
|
||||||
|
)
|
||||||
|
.map((value) => {
|
||||||
|
if (value.children) {
|
||||||
|
value.children = getAuthRoute(value.children, parentPermission || value.permission)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mapJsonToRoute = (jsonObject: RouteJsonObject[]): RouteObject[] => {
|
||||||
|
return jsonObject.map((value) => ({
|
||||||
|
path: value.path,
|
||||||
|
id: value.id,
|
||||||
|
element: value.element,
|
||||||
|
Component: value.component,
|
||||||
|
handle: {
|
||||||
|
absolutePath: value.absolutePath,
|
||||||
|
name: value.name,
|
||||||
|
titlePrefix: value.titlePrefix,
|
||||||
|
title: value.title,
|
||||||
|
titlePostfix: value.titlePostfix,
|
||||||
|
icon: value.icon,
|
||||||
|
menu: value.menu,
|
||||||
|
auth: value.auth,
|
||||||
|
permission: value.permission,
|
||||||
|
autoHide: value.autoHide
|
||||||
|
},
|
||||||
|
children: value.children && mapJsonToRoute(value.children)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setTitle = (jsonObject: RouteJsonObject[], title: string): RouteJsonObject[] => {
|
||||||
|
return jsonObject.map((value) => {
|
||||||
|
if (!value.title) {
|
||||||
|
value.title = title
|
||||||
|
}
|
||||||
|
value.children && setTitle(value.children, title)
|
||||||
|
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user