Commit b5cb5b84 authored by duanledexianxianxian's avatar duanledexianxianxian

sync

parent fe5b0a3c
...@@ -89,6 +89,10 @@ export default { ...@@ -89,6 +89,10 @@ export default {
path: '/', path: '/',
component: '../layouts/BlankLayout', component: '../layouts/BlankLayout',
routes: [ routes: [
{
path: '/404',
component: './404',
},
{ {
path: '/user', path: '/user',
component: '../layouts/UserLayout', component: '../layouts/UserLayout',
...@@ -108,8 +112,12 @@ export default { ...@@ -108,8 +112,12 @@ export default {
path: '/', path: '/',
component: '../layouts/BasicLayout', component: '../layouts/BasicLayout',
Routes: ['src/pages/Authorized'], Routes: ['src/pages/Authorized'],
authority: ['admin', 'user'], authority: ['user'],
routes: [ routes: [
{
path: '/',
redirect: '/dashboard/analysis',
},
{ {
path: '/dashboard', path: '/dashboard',
name: 'dashboard', name: 'dashboard',
...@@ -302,11 +310,7 @@ export default { ...@@ -302,11 +310,7 @@ export default {
icon: 'highlight', icon: 'highlight',
path: '/parameter', path: '/parameter',
component: './system/parameter', component: './system/parameter',
}, authority: ['user'],
{
path: '/',
redirect: '/dashboard/analysis',
authority: ['admin', 'user'],
}, },
], ],
}, },
......
...@@ -20,6 +20,7 @@ const Authorized: React.FunctionComponent<AuthorizedProps> = ({ ...@@ -20,6 +20,7 @@ const Authorized: React.FunctionComponent<AuthorizedProps> = ({
authority, authority,
noMatch = null, noMatch = null,
}) => { }) => {
console.log('noMatch1', noMatch);
const childrenRender: React.ReactNode = typeof children === 'undefined' ? null : children; const childrenRender: React.ReactNode = typeof children === 'undefined' ? null : children;
const dom = check(authority, childrenRender, noMatch); const dom = check(authority, childrenRender, noMatch);
return <>{dom}</>; return <>{dom}</>;
......
...@@ -24,6 +24,10 @@ const checkPermissions = <T, K>( ...@@ -24,6 +24,10 @@ const checkPermissions = <T, K>(
target: T, target: T,
Exception: K, Exception: K,
): T | K | React.ReactNode => { ): T | K | React.ReactNode => {
console.log('authority:', authority);
console.log('currentAuthority:', currentAuthority);
console.log('target:', target);
console.log('noMatch2', Exception);
// 没有判定权限.默认查看所有 // 没有判定权限.默认查看所有
// Retirement authority, return target; // Retirement authority, return target;
if (!authority) { if (!authority) {
...@@ -38,6 +42,7 @@ const checkPermissions = <T, K>( ...@@ -38,6 +42,7 @@ const checkPermissions = <T, K>(
} else if (authority.includes(currentAuthority)) { } else if (authority.includes(currentAuthority)) {
return target; return target;
} }
console.log('noMatch3', Exception);
return Exception; return Exception;
} }
// string 处理 // string 处理
......
...@@ -10,6 +10,8 @@ type CurrentAuthorityType = string | string[] | (() => typeof CURRENT); ...@@ -10,6 +10,8 @@ type CurrentAuthorityType = string | string[] | (() => typeof CURRENT);
const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthorityType) => T) => ( const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthorityType) => T) => (
currentAuthority: CurrentAuthorityType, currentAuthority: CurrentAuthorityType,
): T => { ): T => {
console.log('currentAuthoritycurrentAuthority', currentAuthority);
if (currentAuthority) { if (currentAuthority) {
if (typeof currentAuthority === 'function') { if (typeof currentAuthority === 'function') {
CURRENT = currentAuthority(); CURRENT = currentAuthority();
...@@ -23,6 +25,7 @@ const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthority ...@@ -23,6 +25,7 @@ const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthority
} else { } else {
CURRENT = 'NULL'; CURRENT = 'NULL';
} }
console.log('CURRENT', CURRENT);
return Authorized; return Authorized;
}; };
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* You can view component api by: * You can view component api by:
* https://github.com/ant-design/ant-design-pro-layout * https://github.com/ant-design/ant-design-pro-layout
*/ */
import { ConnectProps, ConnectState } from '@/models/connect'; import { ConnectProps, ConnectState, Dispatch } from '@/models/connect';
import ProLayout, { import ProLayout, {
MenuDataItem, MenuDataItem,
BasicLayoutProps as ProLayoutProps, BasicLayoutProps as ProLayoutProps,
...@@ -13,12 +13,15 @@ import ProLayout, { ...@@ -13,12 +13,15 @@ import ProLayout, {
import React, { useState } from 'react'; import React, { useState } from 'react';
import Authorized from '@/utils/Authorized'; import Authorized from '@/utils/Authorized';
import Link from 'umi/link'; import Link from 'umi/link';
import router from 'umi/router';
import RightContent from '@/components/GlobalHeader/RightContent'; import RightContent from '@/components/GlobalHeader/RightContent';
import { connect } from 'dva'; import { connect } from 'dva';
import { formatMessage } from 'umi-plugin-react/locale'; import { formatMessage } from 'umi-plugin-react/locale';
import { isAntDesignPro } from '@/utils/utils'; import { isAntDesignPro } from '@/utils/utils';
import logo from '../assets/logo.svg'; import { message } from 'antd';
import store from '@/utils/store';
import user from 'mock/user';
export interface BasicLayoutProps extends ProLayoutProps, Omit<ConnectProps, 'location'> { export interface BasicLayoutProps extends ProLayoutProps, Omit<ConnectProps, 'location'> {
breadcrumbNameMap: { breadcrumbNameMap: {
[path: string]: MenuDataItem; [path: string]: MenuDataItem;
...@@ -69,20 +72,44 @@ const footerRender: BasicLayoutProps['footerRender'] = (_, defaultDom) => { ...@@ -69,20 +72,44 @@ const footerRender: BasicLayoutProps['footerRender'] = (_, defaultDom) => {
); );
}; };
const loadInitData = (dispatch: Dispatch) => {
Promise.all([dispatch({ type: 'public/getUserInfo' }), dispatch({ type: 'public/getUserInfo' })]);
};
const BasicLayout: React.FC<BasicLayoutProps> = props => { const BasicLayout: React.FC<BasicLayoutProps> = props => {
const { dispatch, children, settings } = props; const { dispatch, children, settings } = props;
/** /**
* constructor * constructor
*/ */
const [loaded, setLoaded] = useState(false);
useState(() => { useState(() => {
if (dispatch) { if (dispatch) {
// 查看当前用户是否在登录状态
dispatch({ dispatch({
type: 'user/fetchCurrent', type: 'user/checkUserLoginStatus',
}); }).then(({ code, data = false }: { code: string; data: boolean }) => {
dispatch({ setLoaded(true);
type: 'settings/getSetting', if (code === 'sys.success') {
// 登录成功
if (data) {
loadInitData(dispatch);
} else if (store.get('userId')) {
store.set('token', '');
store.set('userId', '');
message.error('登录已过期,请重新登录!');
router.push('/user/login');
} else {
// 此处应该跳转到404或者403页面为佳
// message.error("用户未登录,请先登录系统!");
router.push('/404');
}
}
}); });
// dispatch({
// type: 'settings/getSetting',
// });
} }
}); });
/** /**
...@@ -97,45 +124,47 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => { ...@@ -97,45 +124,47 @@ const BasicLayout: React.FC<BasicLayoutProps> = props => {
}); });
return ( return (
<div className="kim-layout"> loaded && (
<ProLayout <div className="kim-layout">
siderWidth={200} <ProLayout
logo={false} siderWidth={200}
navTheme="dark" logo={false}
onCollapse={handleMenuCollapse} navTheme="dark"
menuItemRender={(menuItemProps, defaultDom) => ( onCollapse={handleMenuCollapse}
<Link to={menuItemProps.path}>{defaultDom}</Link> menuItemRender={(menuItemProps, defaultDom) => (
)} <Link to={menuItemProps.path}>{defaultDom}</Link>
breadcrumbRender={(routers = []) => [ )}
{ breadcrumbRender={(routers = []) => [
path: '/', {
breadcrumbName: formatMessage({ path: '/',
id: 'menu.home', breadcrumbName: formatMessage({
defaultMessage: 'Home', id: 'menu.home',
}), defaultMessage: 'Home',
}, }),
...routers, },
]} ...routers,
footerRender={false} // 不显示footer ]}
menuDataRender={menuDataRender} // 渲染导航菜单列表 footerRender={false} // 不显示footer
formatMessage={formatMessage} menuDataRender={menuDataRender} // 渲染导航菜单列表
rightContentRender={rightProps => <RightContent {...rightProps} />} formatMessage={formatMessage}
{...props} rightContentRender={rightProps => <RightContent {...rightProps} />}
{...settings} {...props}
> {...settings}
{children} >
</ProLayout> {children}
{/* 主题设置抽屉 */} </ProLayout>
<SettingDrawer {/* 主题设置抽屉 */}
settings={settings} <SettingDrawer
onSettingChange={config => settings={settings}
dispatch({ onSettingChange={config =>
type: 'settings/changeSetting', dispatch({
payload: config, type: 'settings/changeSetting',
}) payload: config,
} })
/> }
</div> />
</div>
)
); );
}; };
......
...@@ -22,6 +22,7 @@ export interface GlobalModelType { ...@@ -22,6 +22,7 @@ export interface GlobalModelType {
fetchNotices: Effect; fetchNotices: Effect;
clearNotices: Effect; clearNotices: Effect;
changeNoticeReadState: Effect; changeNoticeReadState: Effect;
checkUserLoginStatus: Effect;
}; };
reducers: { reducers: {
changeLayoutCollapsed: Reducer<GlobalModelState>; changeLayoutCollapsed: Reducer<GlobalModelState>;
......
import { queryCurrent, query as queryUsers } from '@/services/user'; import { queryCurrent, query as queryUsers, checkUserLoginStatus } from '@/services/user';
import { Effect } from 'dva'; import { Effect } from 'dva';
import { Reducer } from 'redux'; import { Reducer } from 'redux';
...@@ -26,6 +26,7 @@ export interface UserModelType { ...@@ -26,6 +26,7 @@ export interface UserModelType {
effects: { effects: {
fetch: Effect; fetch: Effect;
fetchCurrent: Effect; fetchCurrent: Effect;
checkUserLoginStatus: Effect;
}; };
reducers: { reducers: {
saveCurrentUser: Reducer<UserModelState>; saveCurrentUser: Reducer<UserModelState>;
...@@ -55,6 +56,10 @@ const UserModel: UserModelType = { ...@@ -55,6 +56,10 @@ const UserModel: UserModelType = {
payload: response, payload: response,
}); });
}, },
*checkUserLoginStatus({ payload }, { call }) {
const res = yield call(checkUserLoginStatus, payload);
return res;
},
}, },
reducers: { reducers: {
......
...@@ -18,7 +18,7 @@ const NoFoundPage: React.FC<{}> = () => ( ...@@ -18,7 +18,7 @@ const NoFoundPage: React.FC<{}> = () => (
<br /> <br />
<h1>404</h1> <h1>404</h1>
<p>Sorry, the page you visited does not exist.</p> <p>Sorry, the page you visited does not exist.</p>
<Button type="primary" onClick={() => router.push('/')}> <Button type="primary" onClick={() => router.push('/user/login')}>
Back Home Back Home
</Button> </Button>
</div> </div>
......
...@@ -15,17 +15,23 @@ const getRouteAuthority = (path: string, routeData: Route[]) => { ...@@ -15,17 +15,23 @@ const getRouteAuthority = (path: string, routeData: Route[]) => {
routeData.forEach(route => { routeData.forEach(route => {
// match prefix // match prefix
if (pathToRegexp(`${route.path}(.*)`).test(path)) { if (pathToRegexp(`${route.path}(.*)`).test(path)) {
// exact match console.log('----------------------');
if (route.path === path) { console.log('route.path:', route.path);
authorities = route.authority || authorities; console.log('path:', path);
} console.log('route.authority:', route.authority);
authorities = route.authority || authorities;
// 官方代码好像有问题https://github.com/ant-design/ant-design-pro/commit/4a10734dcf858c6363af719a5886a24ec1115b33#diff-2041540b332693486a24a543b6ba0cc8
// // exact match
// if (route.path === path) {
// authorities = route.authority || authorities;
// }
// get children authority recursively // get children authority recursively
if (route.routes) { if (route.routes) {
authorities = getRouteAuthority(path, route.routes) || authorities; authorities = getRouteAuthority(path, route.routes) || authorities;
} }
} }
}); });
console.log('authorities:', authorities);
return authorities; return authorities;
}; };
...@@ -42,6 +48,10 @@ const AuthComponent: React.FC<AuthComponentProps> = ({ ...@@ -42,6 +48,10 @@ const AuthComponent: React.FC<AuthComponentProps> = ({
const { currentUser } = user; const { currentUser } = user;
const { routes = [] } = route; const { routes = [] } = route;
const isLogin = currentUser && currentUser.name; const isLogin = currentUser && currentUser.name;
console.log('routes:', location.pathname, routes);
console.log('authority:', getRouteAuthority(location.pathname, routes));
console.log('isLogin:', isLogin);
return ( return (
<Authorized <Authorized
authority={getRouteAuthority(location.pathname, routes) || ''} authority={getRouteAuthority(location.pathname, routes) || ''}
......
...@@ -3,6 +3,8 @@ import { login } from '../services'; ...@@ -3,6 +3,8 @@ import { login } from '../services';
import store from '@/utils/store'; import store from '@/utils/store';
import { getPageQuery } from '@/utils'; import { getPageQuery } from '@/utils';
import config from '@/config'; import config from '@/config';
import { setAuthority } from '@/utils/authority';
import { reloadAuthorized } from '@/utils/Authorized';
const initData = {}; const initData = {};
export default { export default {
...@@ -14,6 +16,11 @@ export default { ...@@ -14,6 +16,11 @@ export default {
*login({ payload }, { call, put }) { *login({ payload }, { call, put }) {
const { code, data } = yield call(login, payload); const { code, data } = yield call(login, payload);
if (code === 'sys.success') { if (code === 'sys.success') {
yield put({
type: 'changeLoginStatus',
payload: {},
});
reloadAuthorized();
const { token, userId } = data; const { token, userId } = data;
store.set('token', token); store.set('token', token);
store.set('userId', userId); store.set('userId', userId);
...@@ -34,9 +41,10 @@ export default { ...@@ -34,9 +41,10 @@ export default {
window.location.href = redirect; window.location.href = redirect;
return; return;
} }
} else {
redirect = config.homePage;
} }
// else {
// redirect = config.homePage;
// }
yield put(routerRedux.replace(redirect || '/')); yield put(routerRedux.replace(redirect || '/'));
} }
}, },
...@@ -44,12 +52,10 @@ export default { ...@@ -44,12 +52,10 @@ export default {
reducers: { reducers: {
clearData: () => ({ ...initData }), clearData: () => ({ ...initData }),
changeLoginStatus(state, { payload }) { changeLoginStatus(state, { payload }) {
// setAuthority(payload.currentAuthority); setAuthority('user');
// return { return {
// ...state, ...state,
// status: payload.status, };
// type: payload.type,
// };
}, },
}, },
}; };
import request from '@/utils/request'; import { get } from '@/utils/request';
export async function query(): Promise<any> { export async function query(): Promise<any> {
return request('/api/users'); return get('/api/users');
} }
export async function queryCurrent(): Promise<any> { export async function queryCurrent(): Promise<any> {
return request('/api/currentUser'); return get('/api/currentUser');
} }
export async function queryNotices(): Promise<any> { export async function queryNotices(): Promise<any> {
return request('/api/notices'); return get('/api/notices');
} }
/**
* 查看是否已经登录
*/
export const checkUserLoginStatus = () => get(`/api/v1/login/status`);
...@@ -15,6 +15,10 @@ export function getAuthority(str?: string): string | string[] { ...@@ -15,6 +15,10 @@ export function getAuthority(str?: string): string | string[] {
if (typeof authority === 'string') { if (typeof authority === 'string') {
return [authority]; return [authority];
} }
console.log(
'ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION',
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION,
);
// preview.pro.ant.design only do not use in your production. // preview.pro.ant.design only do not use in your production.
// preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 // preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
if (!authority && ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') { if (!authority && ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') {
......
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