Commit 75a248e2 authored by 前端-许佳敏's avatar 前端-许佳敏

权限路由模式添加

parent 17c0bcfc
......@@ -6,6 +6,7 @@ import shopRoute from './shopRoutes'
* @description 路由配置页, 更多配置可查看 https://umijs.org/zh-CN/docs/routing#routes
*/
const router = [
{
path: '/',
component: '@/wrappers/getSiteConfig',
......@@ -33,20 +34,14 @@ const router = [
]
},
memberCenterRoute,
shopRoute,
{
component: '@/pages/404',
},
shopRoute
],
},
{
path: '/404',
component: '@/pages/404',
},
{
path: '/500',
component: '@/pages/500',
},
}
]
export const asyncRouterLists = {
memberCenterRoute,
shopRoute
}
export default router
\ No newline at end of file
......@@ -11,7 +11,6 @@ const CommodityRoute = {
name: 'commodityAbility',
key: 'commodityAbility',
icon: 'smile',
menuCode: '',
routes: [
{
path: '/memberCenter/commodityAbility/classAndProperty',
......@@ -22,7 +21,6 @@ const CommodityRoute = {
path: '/memberCenter/commodityAbility/classAndProperty/class',
name: 'class',
icon: 'smile',
menuCode: '/memberCenter/commodityAbility/classAndProperty/class',
component: '@/pages/classAndProperty/class',
},
{
......
......@@ -33,6 +33,11 @@ const memberCenterRoute = {
},
...routes,
{
path: '/noAuth',
component: '@/pages/403',
},
// 能力中心的404页
{
component: '@/pages/404',
},
],
......
......@@ -2,21 +2,30 @@
const shopRoute = {
path: '/',
component: "@/layouts/BlankLayout",
extra: true,
routes: [
{
// 首页
path: `/`,
name: 'home',
key: 'home',
component: '@/pages/shopCenter/index',
},
{
// 资讯
path: `/information`,
name: 'home',
key: 'home',
name: 'info',
component: '@/pages/index',
},
{
path: '/noAuth',
component: '@/pages/403',
},
// 商城页的404
{
component: '@/pages/404',
},
],
}
......
import { IRoutes } from '.';
import { history, RequestConfig } from 'umi';
import { history, RequestConfig, Redirect } from 'umi';
import React from 'react'
import MobxProvider from './store'
import '@/global/styles/reset.less'; // 重置antd样式
......@@ -9,23 +9,24 @@ import '@/global/styles/global.less'; // 导入全局样式
import 'antd/dist/antd.less'
import { setup } from '@formily/antd-components';
import { GlobalConfig } from './global/config';
import { asyncRouter } from './utils/asyncRouter';
import { getRouters, getAuth } from './utils/auth';
setup()
const mockFetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([
{ menuCode: '/memberCenter/commodityAbility' },
{ menuCode: '/memberCenter/commodityAbility/classAndProperty/class' },
])
}, 2000)
})
}
let extraRoutes: any[] = []
// let routeAuthUrls: any[] = []
// 路由白名单
const whiteLists = [
'/',
'/user/login',
'/user/register',
'/memberCenter',
'/404',
'/noAuth'
]
/**
* @description 配置函数,对已配置的路由做修改, 一般与render函数一起结合可根据接口动态配置路由
* @description 配置函数,对已配置的路由做修改, 一般与render函数一起结合可根据接口动态配置路由, 直接修改routes即可
* @author xjm
* @date 2020-05-20
* @export
......@@ -38,11 +39,9 @@ let extraRoutes: any[] = []
* });
*
*/
// export function patchRoutes({ routes }: IRoutes) {
// GlobalConfig.global.menuList.map(v => v.menuCode)
// console.log(routes)
// }
export function patchRoutes({ routes }: IRoutes) {
asyncRouter(getRouters(), routes)
}
/**
* @description 用于渲染前所做的事, 比如动态路由,权限校验等
......@@ -50,25 +49,9 @@ let extraRoutes: any[] = []
* @date 2020-05-20
* @export
*/
// export function render(oldRender:Function) {
// mockFetchData().then((res: any[]) => {
// extraRoutes = res
// })
// // 做动态路由
// // fetch('/api').then((res: any) => {
// // extraRoutes = res.routes
// // })
// // // 做权限校验
// // fetch('/auth').then((res: any) => {
// // if (res.isLogin) {
// // oldRender()
// // } else {
// // history.push('/login')
// // }
// // })
// }
export function render(oldRender:Function) {
oldRender()
}
/**
* @description 在初始加载和路由切换时做一些事情
......@@ -77,9 +60,22 @@ let extraRoutes: any[] = []
* @export
* @param {*} { routes, matchedRoutes, location, action }
*/
// export function onRouteChange({ routes, matchedRoutes, location, action }) {
// console.log(routes, matchedRoutes, location, action)
// }
export function onRouteChange({ routes, matchedRoutes, location, action }) {
console.log(`当前可访问的路由为`)
console.log(routes)
if (whiteLists.includes(location.pathname)) return ;
const routeAuthUrls = getRouters()
if (getAuth()) {
if (routeAuthUrls.includes(location.pathname)) {
} else {
history.replace('/')
}
} else {
history.replace('/404')
}
}
/**
......
......@@ -204,7 +204,7 @@ const TabTree:React.FC<TabTreeProps> = (props) => {
if (props.handleSelect) {
const result = props.handleSelect(node.key, node)
// 存在返回值则不执行选中事件, 一般用于切换node时,不希望离开当前页面
if (result !== undefined) {
if (result) {
result.then(() => {
// 若promise 是resolve状态, 说明确认离开了当前页面
setSelectKey(selectKey === node.key ? '' : node.key)
......
import React from 'react'
export interface BlankLayoutProps {}
const BlankLayout:React.FC<BlankLayoutProps> = (props) => {
return <div>{props.children}</div>
}
BlankLayout.defaultProps = {}
export default BlankLayout
\ No newline at end of file
......@@ -2,12 +2,19 @@ import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons
import { Avatar, Menu, Spin } from 'antd';
import { ClickParam } from 'antd/es/menu';
import React from 'react';
// import { history, ConnectProps, connect } from 'umi';
import { history } from 'umi';
import PersonDropdown from './PersonDropdown'
import styles from '../styles/RightContent.less';
import { removeAuth, removeRouters } from '@/utils/auth';
const AvatarDropdown = () => {
const logout = () => {
removeAuth()
removeRouters()
history.replace('/user/login')
}
const currentUser = {
name: 'Serati Ma',
avatar: 'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png',
......@@ -24,7 +31,7 @@ const AvatarDropdown = () => {
个人设置
</Menu.Item>
<Menu.Divider />
<Menu.Item key="logout">
<Menu.Item onClick={logout} key="logout">
<LogoutOutlined />
退出登录
</Menu.Item>
......
......@@ -3,6 +3,7 @@ import { Layout, Menu } from 'antd'
import { AppstoreOutlined } from '@ant-design/icons'
import { Link } from 'umi'
import styles from '../styles/MenuSlider.less'
import { getRouters } from '@/utils/auth'
const { Sider } = Layout
......@@ -13,6 +14,7 @@ export interface OuterSiderProps {
const OuterSider: React.FC<OuterSiderProps> = (props) => {
const { menuData, pathname = "/" } = props
const authRouters = getRouters()
let defaultSelectedKeys: string = ""
const getSubMenu = () => {
const subHeadMenus: Array<any> = []
......@@ -20,7 +22,7 @@ const OuterSider: React.FC<OuterSiderProps> = (props) => {
if (pathname.indexOf(item.key) > -1) {
defaultSelectedKeys = item.key
}
!item.hideInMenu && subHeadMenus.push({
!item.hideInMenu && authRouters.includes(item.path) && subHeadMenus.push({
path: item.path,
title: item.name,
icon: item.icon,
......@@ -29,14 +31,13 @@ const OuterSider: React.FC<OuterSiderProps> = (props) => {
})
return subHeadMenus
}
const siderMunu = getSubMenu()
const siderMenu = getSubMenu()
return <>
<Sider collapsed={true} collapsedWidth={64} className={styles.wrapperSilder}>
<div className={styles.userPic} />
<ul className={styles.menuBox}>
{
siderMunu.map(item => (
siderMenu.map(item => (
!item.hideInMenu && <li key={item.key} className={defaultSelectedKeys === item.key ? styles.currentItem : ''}>
<Link to={item.path}>
<AppstoreOutlined />
......
import React from 'react';
import { history } from 'umi';
import { Button, Row, Col } from 'antd';
import { GlobalConfig } from '@/global/config';
import UserHeader from '../layouts/components/UserHeader';
import styles from './index.less'
import Img from '../../mockStatic/illus.png'
const NoFoundPage: React.FC<{}> = () => {
const handleReturn = () => {
history.replace('/user/login')
}
return (
<div className={styles.wrapper}>
<UserHeader logo={GlobalConfig.global.logo}/>
<div className={styles.errorBox}>
<Row>
<Col span={12}>
<div className={styles.desc}>
<h1>您当前无权访问该页面</h1>
<Button
type="primary"
size="large"
style={{marginTop: 100}}
onClick={handleReturn}
>重新登录</Button>
</div>
</Col>
<Col span={12}>
<img className={styles.image} src={Img} alt="数商云服务"/>
</Col>
</Row>
</div>
</div>
)
}
export default NoFoundPage;
......@@ -28,7 +28,7 @@ const fetchMemberList = async (params) => {
return res.data
}
const fetchProductList = async (params) => {
const res = await PublicApi.getProductCommodityGetCommodityList(params)
const res = await PublicApi.getProductCommodityGetCommodityDetailList(params)
return res.data
}
......
......@@ -29,8 +29,9 @@ const fetchMemberList = async (params) => {
const res = await PublicApi.getMemberMaintenancePage(params)
return res.data
}
const fetchProductList = async (params) => {
const res = await PublicApi.getProductCommodityGetCommodityList(params)
const res = await PublicApi.getProductCommodityGetCommodityDetailList(params)
return res.data
}
......
......@@ -8,7 +8,7 @@ import {
} from '@ant-design/icons';
import styles from '../index.less'
import { PublicApi } from '@/services/api';
import { setAuth } from '@/utils/auth';
import { setAuth, setRouters } from '@/utils/auth';
const LoginWrap: React.FC = () => {
const [validFrame, setValidFrame] = useState(false)
......@@ -23,7 +23,8 @@ const LoginWrap: React.FC = () => {
userId: data.userId,
token: data.token
})
history.push('/')
setRouters(data.urls)
history.push('/memberCenter/home')
})
}
......
export const asyncRouter = async (routeLists: string[], routes: any[]) => {
for (let i = 0; i < routes.length; i++) {
const item = routes[i]
if (item.routes) {
asyncRouter(routeLists, item.routes)
} else {
// 参与权限校验的页面
if (item.path && !routeLists.includes(item.path)) {
item.hideInMenu = true
item.noAuth = true
}
}
}
}
......@@ -10,8 +10,28 @@ export const setAuth = (info: AuthInfo) => {
export const getAuth = () => {
try {
return JSON.parse(window.localStorage.getItem('auth'))
return JSON.parse(window.localStorage.getItem('auth')) || {}
} catch (error) {
return {}
}
}
export const setRouters = (routers: any[]) => {
window.sessionStorage.setItem('rt', JSON.stringify(routers))
}
export const getRouters = () => {
try {
return JSON.parse(window.sessionStorage.getItem('rt')) || []
} catch (error) {
return []
}
}
export const removeRouters = () => {
window.sessionStorage.removeItem('rt')
}
export const removeAuth = () => {
window.localStorage.removeItem('auth')
}
......@@ -2,7 +2,8 @@ import { extend, ResponseError, OnionOptions, RequestOptionsInit, ResponseInterc
import responseCode from '@/constants/responseCode'
import { IRequestError, IRequestSuccess } from '..';
import { message } from 'antd'
import { getAuth } from './auth';
import { getAuth, removeAuth } from './auth';
import { history } from 'umi'
export type CtlType = 'none' | 'message'
// 根前缀请求路径
......@@ -102,12 +103,20 @@ class ApiRequest {
createRequest<T>(url: string, options: IApiRequest = { ctlType: 'none' }): Promise<IRequestSuccess<T>> {
return new Promise((resolve, reject) => {
baseRequest<IRequestSuccess<T>>(url, options).then(res => {
// 登录验证
if (res.code === 1101) {
removeAuth()
history.replace('/user/login')
return false
}
if (res.code === 1000) {
options.ctlType === 'message' && message.success(res.message)
resolve(res)
} else {
message.error(res.message)
}
}).catch((err: IRequestError) => {
// http错误处理, 直接透传
reject(err)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment