Commit 032b6c96 authored by 前端-许佳敏's avatar 前端-许佳敏

加入权限控制

parent e9e3714b
......@@ -36,10 +36,14 @@ const router = [
component: '@/pages/home',
icon: 'BarChartOutlined'
},
...routeList
...routeList,
{
path: '/noAuth',
hidePageHeader: true,
component: '@/pages/403'
}
]
},
]
export default router
......@@ -41,6 +41,7 @@
"mobx": "^5.15.4",
"mobx-react": "^6.2.2",
"prettier": "^1.19.1",
"query-string": "^6.13.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"umi": "^3.2.0",
......
......@@ -8,12 +8,19 @@ import '@/global/styles/global.less'; // 导入全局样式
// 默认引入所有的ant样式, 不引入css因为无法做到变量覆盖
import 'antd/dist/antd.less';
import { setup } from '@formily/antd-components';
import { getAuth, setAuth, setRouters } from './utils/auth';
import { getAuth, setAuth, setRouters, removeAuth, removeRouters, asyncRouter, getRouters } from './utils/auth';
import { PublicApi } from './services/api';
import { isDev } from './constants';
import queryString from 'query-string';
setup();
let extraRoutes: never[] = [];
const whiteLists = [
'/',
'/login',
'/noAuth'
]
/**
* @description 配置函数,对已配置的路由做修改, 一般与render函数一起结合可根据接口动态配置路由
* @author xjm
......@@ -28,9 +35,12 @@ let extraRoutes: never[] = [];
* });
*
*/
// export function patchRoutes({ routes }: IRoutes) {
// routes.concat(extraRoutes as [])
// }
export function patchRoutes({ routes }: IRoutes) {
if (isDev) {
return;
}
asyncRouter(getRouters(), routes)
}
/**
* @description 用于渲染前所做的事, 比如动态路由,权限校验等
......@@ -42,17 +52,25 @@ export function render(oldRender:Function) {
const authInfo = getAuth()
if (authInfo) {
PublicApi.getMemberManageLoginReget().then(res => {
const { data } = res
setAuth({
memberId: data.memberId,
userId: data.userId,
token: data.token
})
setRouters(data.urls)
const { data, code } = res
if (code === 1000) {
setAuth({
memberId: data.memberId,
userId: data.userId,
token: data.token
})
setRouters(data.urls)
} else {
removeAuth()
removeRouters()
history.push('/login')
}
oldRender()
})
} else {
oldRender()
}
oldRender()
}
/**
......@@ -62,9 +80,39 @@ export function render(oldRender:Function) {
* @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('onRouteChange')
// if (isDev) {
// return;
// }
if (whiteLists.includes(location.pathname)) return;
const routeAuthUrls = getRouters()
// 是否登录
if (getAuth()) {
const { query, pathname } = location
// 固定配置, 出现此参数说明需携带参数校验权限路由
if (query.page_type && routeAuthUrls.find(authPath => {
const parseUrl = queryString.parseUrl(authPath)
const { query: selfQuery, url } = parseUrl
// 当页面出现参数page_type时, 需进入深度校验, 即对应的参数和路径匹配
return url === pathname && selfQuery.page_type === query.page_type
})) {
// 深度匹配成功, 可正常访问
return ;
}
// 是否在路由权限列表里
if (routeAuthUrls.includes(pathname)) {
return ;
}
// 无权限访问时
history.replace('/noAuth')
} else {
history.replace('/login')
}
}
/**
* @description 可对最外层做容器包裹
......
export const NOT_CHANGE_VALUE = 'hello, world'
// 本地环境跳过权限校验
export const isDev = process.env.NODE_ENV === "development"
\ No newline at end of file
export const isDev = process.env.NODE_ENV === "development"
// export const isDev = false
\ No newline at end of file
......@@ -7,7 +7,7 @@ const { onFormInit$ } = FormEffectHooks
* @param name 待处理的表单路径
* @param service 触发的异步函数, 需返回一个{label: any, value: any}形式的数组
*/
export const useAsyncInitSelect = (name: string[], service?: () => Promise<any>) => {
export const useAsyncInitSelect = (name: string[], service: () => Promise<any>) => {
const { dispatch, setFieldState } = createFormActions()
const linkage = useLinkageUtils()
onFormInit$().subscribe(() => {
......@@ -21,7 +21,7 @@ export const useAsyncInitSelect = (name: string[], service?: () => Promise<any>)
linkage.enum(v, res[v])
})
//请求结束可以dispatch一个自定义事件收尾,方便后续针对该事件做联动
dispatch('requestAsyncSelect', {
dispatch && dispatch('requestAsyncSelect', {
name,
payload: res
})
......
......@@ -6,6 +6,8 @@ import MenuUtil from '@/utils/menu'
import { useIntl } from 'umi'
import { MenuDataItem } from '@/utils/typing'
import { getMatchMenu } from '@umijs/route-utils'
import { isDev } from '@/constants'
import { getRouters } from '@/utils/auth'
// 获取当前的选中菜单
export const getSelectedMenuKeys = (
pathname: string,
......@@ -38,7 +40,14 @@ const MenuSlider = (props) => {
const menuUtil = new MenuUtil({
formatMessage,
})
console.log(menuData)
// 本地可无权限访问所有路由
if (!isDev) {
menuData
}
const dispatchRoutes = menuData.filter(v => getRouters().includes(v.path))
return (
<Slider className={styles.lxSlider} collapsed={props.collapseState} width={240}>
<Logo />
......@@ -49,7 +58,7 @@ const MenuSlider = (props) => {
defaultOpenKeys={defaultOpenKeysRef.current}
className={styles.lxSliderMenu}
>
{menuUtil.getNavMenuItems(menuData)}
{menuUtil.getNavMenuItems(dispatchRoutes)}
</Menu>
</Slider>
)
......
import React from 'react';
import { history } from 'umi';
import { Button, Row, Col } from 'antd';
import { GlobalConfig } from '@/global/config';
import styles from './index.less'
import Img from '../../static/illus.png'
const NoFoundPage: React.FC<{}> = () => {
const handleReturn = () => {
history.replace('/home')
}
return (
<div className={styles.wrapper}>
<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;
.normal {
}
.title {
font-size: 24px;
color: #666;
}
// 500 error
// .wrapper{
// }
.errorBox{
width: 100%;
.desc{
width: 400px;
margin: 200px auto 0;
}
.image {
display: block;
width: 100%;
height: 100%;
}
}
......@@ -87,7 +87,7 @@ class Index extends Component<{}, IndexState> {
token: data.token
})
setRouters(data.urls)
history.push('/')
window.location.href = '/home'
}).catch(error => {
console.error(error)
});
......
import { isDev } from '@/constants'
export interface AuthInfo {
userId: number,
memberId: number,
......@@ -10,20 +12,21 @@ export const setAuth = (info: AuthInfo) => {
export const getAuth = () => {
try {
return JSON.parse(window.localStorage.getItem('auth') || '') || null
const localAuth = window.localStorage.getItem('auth')
return localAuth ? JSON.parse(localAuth) : null
} 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') || '') || []
const sessionRt = window.sessionStorage.getItem('rt')
return sessionRt ? JSON.parse(sessionRt) : []
} catch (error) {
return []
}
......
......@@ -3,7 +3,7 @@ import responseCode from '@/constants/responseCode'
import { IRequestError, IRequestSuccess } from '..';
import { history } from 'umi'
import { message } from 'antd'
import { getAuth, removeAuth } from './auth';
import { getAuth, removeAuth, removeRouters } from './auth';
import { isDev } from '@/constants';
export type CtlType = 'none' | 'message'
......@@ -96,6 +96,7 @@ class ApiRequest {
return ;
}
removeAuth()
removeRouters()
history.replace('/login')
return false
}
......
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