对接登录和退出登录
This commit is contained in:
@ -1,24 +1,41 @@
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
// 获取用户信息 这里没用dva, 因为包装组件写法复杂(当前框架),尤其是有form表单组件时
|
||||
export const useUser = () => {
|
||||
const [user, setUser] = useState<any>({
|
||||
role: 'admin1', // 模拟用户权限
|
||||
role: 'admin1', // 初始默认值
|
||||
});
|
||||
const getUserInfo = ()=>{
|
||||
return user;
|
||||
}
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// 获取用户信息
|
||||
const getUserInfo = async () => {
|
||||
return JSON.parse(sessionStorage.getItem('userInfo') || user || '{}');
|
||||
};
|
||||
|
||||
const setUserInfo = (userInfo: any) => {
|
||||
sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
|
||||
setUser(userInfo);
|
||||
}
|
||||
const getUserRole = ()=>{
|
||||
};
|
||||
|
||||
const getUserRole = () => {
|
||||
return user.role;
|
||||
}
|
||||
};
|
||||
|
||||
const setToken = (token: string) => {
|
||||
sessionStorage.setItem('token', token);
|
||||
}
|
||||
};
|
||||
|
||||
const getToken = () => {
|
||||
return sessionStorage.getItem('token');
|
||||
}
|
||||
return { user, getUserInfo, setUserInfo, getUserRole, setToken, getToken };
|
||||
};
|
||||
|
||||
return {
|
||||
user,
|
||||
loading,
|
||||
getUserInfo,
|
||||
setUserInfo,
|
||||
getUserRole,
|
||||
setToken,
|
||||
getToken
|
||||
};
|
||||
};
|
||||
|
@ -1,11 +1,70 @@
|
||||
import React from 'react';
|
||||
import { Link, useIntl } from 'umi';
|
||||
const User: React.FC = (props) => {
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Link, useIntl, connect, history } from 'umi';
|
||||
import { Dropdown, Button, Modal } from 'antd';
|
||||
import { DownOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
|
||||
import type { ConnectProps, Dispatch } from 'umi';
|
||||
import type { UserModelState } from '@/models/user';
|
||||
import { message } from 'antd';
|
||||
|
||||
interface PageProps extends ConnectProps {
|
||||
user: UserModelState; // dva model状态
|
||||
dispatch: Dispatch; // dva dispatch方法
|
||||
}
|
||||
const User: React.FC<PageProps> = ({ user, dispatch }) => {
|
||||
const intl = useIntl();
|
||||
useEffect(() => {
|
||||
if (user.token) {
|
||||
dispatch({
|
||||
type: 'user/fetchUserInfo',
|
||||
});
|
||||
}
|
||||
}, [user.token]);
|
||||
const handleMenuClick = (e: any) => {
|
||||
if (e.key === 'logout') {
|
||||
Modal.confirm({
|
||||
title: '确定退出登录吗?',
|
||||
icon: <ExclamationCircleOutlined />,
|
||||
content: '退出登录后,您将需要重新登录',
|
||||
onOk() {
|
||||
dispatch({
|
||||
type: 'user/logout',
|
||||
}).then(() => {
|
||||
sessionStorage.clear();
|
||||
message.success('退出登录成功');
|
||||
history.push('/login');
|
||||
});
|
||||
},
|
||||
onCancel() {
|
||||
return;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="user">
|
||||
<Link to={'/login'}>{intl.formatMessage({ id: '登录' })}</Link>
|
||||
{user.userInfo?.fullName ? (
|
||||
<Dropdown
|
||||
trigger={['hover']}
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
key: 'logout',
|
||||
label: '退出登录',
|
||||
},
|
||||
],
|
||||
onClick: handleMenuClick,
|
||||
}}
|
||||
>
|
||||
<Button type="link">
|
||||
{`${user.userInfo?.fullName}`}
|
||||
<DownOutlined />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
) : (
|
||||
<Link to={'/login'}>{intl.formatMessage({ id: '登录' })}</Link>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default User;
|
||||
|
||||
export default connect(({ user }: { user: UserModelState }) => ({ user }))(User);
|
||||
|
@ -1,6 +1,8 @@
|
||||
import breadcrumb from './breadcrumb';
|
||||
import user from './user';
|
||||
|
||||
export default {
|
||||
breadcrumb,
|
||||
user,
|
||||
// ... 其他 models
|
||||
};
|
||||
|
90
src/models/user.ts
Normal file
90
src/models/user.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import type { Effect, Reducer } from 'umi';
|
||||
|
||||
import { getUserinfo, Logout } from '@/servers/api/login';
|
||||
|
||||
|
||||
export type User = {
|
||||
userId: string;
|
||||
userName: string;
|
||||
userType: string;
|
||||
};
|
||||
|
||||
export type UserInfo = {
|
||||
userId: string;
|
||||
fullName: string;
|
||||
loginName: string;
|
||||
userType: string;
|
||||
authorityList: { roleId: string, roleName: string, roleCode: string, roleScope: string }[];
|
||||
};
|
||||
|
||||
export type UserModelState = {
|
||||
user?: User;
|
||||
token?: string;
|
||||
userInfo?: UserInfo;
|
||||
};
|
||||
|
||||
export type UserModelType = {
|
||||
namespace: 'user';
|
||||
state: UserModelState;
|
||||
effects: {
|
||||
fetchUserInfo: Effect;
|
||||
logout: Effect;
|
||||
};
|
||||
reducers: {
|
||||
saveLoginUser: Reducer<UserModelState>;
|
||||
saveUserInfo: Reducer<UserModelState>;
|
||||
clearUserInfo: Reducer;
|
||||
};
|
||||
};
|
||||
|
||||
const UserModel: UserModelType = {
|
||||
namespace: 'user',
|
||||
|
||||
state: {
|
||||
user: undefined, // 登录返回的用户信息
|
||||
token: sessionStorage.getItem('token') || '', // 登录返回的token
|
||||
userInfo: undefined, // 请求userInfo返回的用户信息
|
||||
},
|
||||
|
||||
effects: {
|
||||
*fetchUserInfo(_, { call, put }) {
|
||||
const response = yield call(getUserinfo);
|
||||
yield put({
|
||||
type: 'saveUserInfo',
|
||||
payload: response,
|
||||
});
|
||||
},
|
||||
*logout(_, { call, put }) {
|
||||
yield call(Logout);
|
||||
yield put({
|
||||
type: 'clearUserInfo'
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
reducers: {
|
||||
clearUserInfo(state) {
|
||||
return {
|
||||
...state,
|
||||
userInfo: undefined,
|
||||
token: '',
|
||||
user: {},
|
||||
};
|
||||
},
|
||||
saveLoginUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
user: action.payload.user || {},
|
||||
token: action.payload.token || '',
|
||||
};
|
||||
},
|
||||
saveUserInfo(state, action) {
|
||||
return {
|
||||
...state,
|
||||
userInfo: action.payload || {},
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default UserModel;
|
@ -1,52 +1,49 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Form, Input, Button, Checkbox, Tabs, message } from 'antd';
|
||||
import { UserOutlined, LockOutlined, EyeInvisibleOutlined, EyeTwoTone, HomeOutlined } from '@ant-design/icons';
|
||||
import { history, useIntl } from 'umi';
|
||||
import {
|
||||
UserOutlined,
|
||||
LockOutlined,
|
||||
EyeInvisibleOutlined,
|
||||
EyeTwoTone,
|
||||
HomeOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { history, useIntl, connect } from 'umi';
|
||||
import type { ConnectProps, Dispatch } from 'umi';
|
||||
import './login.less';
|
||||
import { getCaptcha, supplierLogin, expertLogin, accountLogin } from '@/servers/api/login';
|
||||
|
||||
import { encryptWithRsa } from '@/utils/encryptWithRsa'
|
||||
import { getCaptcha, supplierLogin, getUserinfo, findMenuList ,accountLogin} from '@/servers/api/login';
|
||||
import { encryptWithRsa } from '@/utils/encryptWithRsa';
|
||||
import type { UserModelState } from '@/models/user';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
const LoginPage: React.FC = () => {
|
||||
const [activeKey, setActiveKey] = useState('supplierLogin');
|
||||
interface PageProps extends ConnectProps {
|
||||
user: UserModelState; // dva model状态
|
||||
dispatch: Dispatch; // dva dispatch方法
|
||||
}
|
||||
const LoginPage: React.FC<PageProps> = ({ user, dispatch }) => {
|
||||
const [activeKey, setActiveKey] = useState('agent');
|
||||
const [form] = Form.useForm();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [captchaImg, setCaptchaImg] = useState<string>('');
|
||||
const [captchaKey, setCaptchaKey] = useState<string>('');
|
||||
//切换后 走不同接口
|
||||
const loginApiMap: { [key: string]: (params: any) => Promise<any> } = {
|
||||
supplierLogin,
|
||||
expertLogin,
|
||||
accountLogin
|
||||
};
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
|
||||
const [captchaImg, setCaptchaImg] = useState('');
|
||||
const [captchaKey, setCaptchaKey] = useState('');
|
||||
const onFinish = async (values: any) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const params = {
|
||||
...values,
|
||||
password: encryptWithRsa(values.password, false),
|
||||
encryptValue: encryptWithRsa(values.identifying)
|
||||
encryptValue: encryptWithRsa(values.identifying),
|
||||
};
|
||||
const loginRes = await loginApiMap[activeKey](params);
|
||||
const loginRes = await accountLogin(params);
|
||||
if (loginRes.code === 200) {
|
||||
sessionStorage.setItem('token', loginRes.data.token);
|
||||
//存入供应商用户id
|
||||
if(activeKey === 'supplierLogin') {
|
||||
sessionStorage.setItem('userId', loginRes.data.supplierUser.userId);
|
||||
} else if(activeKey === 'expertLogin') {
|
||||
//存入专家用户id
|
||||
// sessionStorage.setItem('userId', loginRes.data.expertUser.userId);
|
||||
} else if(activeKey === 'accountLogin') {
|
||||
//存入招标代理用户id
|
||||
// sessionStorage.setItem('userId', loginRes.data.supplierUser.userId);
|
||||
}
|
||||
sessionStorage.setItem('userId', loginRes.data.user.userId);
|
||||
sessionStorage.setItem('currentUser', JSON.stringify(loginRes.data));
|
||||
dispatch({
|
||||
type: 'user/saveLoginUser',
|
||||
payload: loginRes.data,
|
||||
})
|
||||
message.success('登录成功');
|
||||
history.push('/index');
|
||||
} else {
|
||||
@ -57,19 +54,6 @@ const LoginPage: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const fetchCaptcha = async () => {
|
||||
const res = await getCaptcha();
|
||||
if (res.code === 200) {
|
||||
setCaptchaImg(res.data.base64Image);
|
||||
setCaptchaKey(res.data.code);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchCaptcha();
|
||||
}, [activeKey]);
|
||||
|
||||
const handleTabChange = (key: string) => {
|
||||
setActiveKey(key);
|
||||
form.resetFields();
|
||||
@ -77,11 +61,11 @@ const LoginPage: React.FC = () => {
|
||||
|
||||
// 根据当前选中的Tab决定跳转到哪个注册页面
|
||||
const handleRegister = () => {
|
||||
switch(activeKey) {
|
||||
case 'supplierLogin':
|
||||
switch (activeKey) {
|
||||
case 'supplier':
|
||||
history.push('/register/supplier');
|
||||
break;
|
||||
case 'expertLogin':
|
||||
case 'expert':
|
||||
history.push('/register/expert');
|
||||
break;
|
||||
default:
|
||||
@ -92,49 +76,62 @@ const LoginPage: React.FC = () => {
|
||||
|
||||
// 渲染注册链接(只在供应商和专家Tab下显示)
|
||||
const renderRegisterLink = () => {
|
||||
if (activeKey === 'agent') {
|
||||
if (activeKey === 'agent' || activeKey === 'expert') {
|
||||
return null; // 招标代理不显示注册链接
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="register-link">
|
||||
{intl.formatMessage({ id: 'login.register.tip' })}
|
||||
<a onClick={handleRegister}>
|
||||
{intl.formatMessage({ id: 'login.register.action' })}
|
||||
</a>
|
||||
<a onClick={handleRegister}>{intl.formatMessage({ id: 'login.register.action' })}</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 获取验证码
|
||||
const fetchCaptcha = async () => {
|
||||
const res = await getCaptcha();
|
||||
if (res.code === 200) {
|
||||
setCaptchaImg(res.data.base64Image);
|
||||
setCaptchaKey(res.data.code);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
fetchCaptcha();
|
||||
}, [activeKey]);
|
||||
return (
|
||||
<div className='login-page'>
|
||||
<div className='login-container'>
|
||||
{/* <div className='back-home'>
|
||||
<div className="login-page">
|
||||
<div className="login-container">
|
||||
<div className="back-home">
|
||||
<a onClick={() => history.push('/index')}>
|
||||
<HomeOutlined /> {intl.formatMessage({ id: 'login.back.home' })}
|
||||
</a>
|
||||
</div> */}
|
||||
|
||||
<div className='login-title'>{intl.formatMessage({ id: 'login.title' })}</div>
|
||||
|
||||
<div className="login-tab-container">
|
||||
<Tabs activeKey={activeKey} onChange={handleTabChange} className='login-tabs'>
|
||||
<TabPane tab={intl.formatMessage({ id: 'login.tab.supplier' })} key="supplierLogin" />
|
||||
<TabPane tab={intl.formatMessage({ id: 'login.tab.expert' })} key="expertLogin" />
|
||||
<TabPane tab={intl.formatMessage({ id: 'login.tab.agent' })} key="accountLogin" />
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<div className="login-title">{intl.formatMessage({ id: 'login.title' })}</div>
|
||||
|
||||
{/* <div className="login-tab-container">
|
||||
<Tabs activeKey={activeKey} onChange={handleTabChange} className='login-tabs'>
|
||||
<TabPane tab={intl.formatMessage({ id: 'login.tab.supplier' })} key="supplier" />
|
||||
<TabPane tab={intl.formatMessage({ id: 'login.tab.expert' })} key="expert" />
|
||||
<TabPane tab={intl.formatMessage({ id: 'login.tab.agent' })} key="agent" />
|
||||
</Tabs>
|
||||
</div> */}
|
||||
|
||||
<Form
|
||||
form={form}
|
||||
name="login"
|
||||
className='login-form'
|
||||
className="login-form"
|
||||
initialValues={{ remember: false }}
|
||||
onFinish={onFinish}
|
||||
>
|
||||
<Form.Item
|
||||
name="account"
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'login.username.placeholder' }) + '!' }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'login.username.placeholder' }) + '!',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
prefix={<UserOutlined className="site-form-item-icon" />}
|
||||
@ -145,18 +142,28 @@ const LoginPage: React.FC = () => {
|
||||
|
||||
<Form.Item
|
||||
name="password"
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'login.password.placeholder' }) + '!' }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'login.password.placeholder' }) + '!',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input.Password
|
||||
prefix={<LockOutlined className="site-form-item-icon" />}
|
||||
placeholder={intl.formatMessage({ id: 'login.password.placeholder' })}
|
||||
iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}
|
||||
iconRender={(visible) => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}
|
||||
size="large"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="identifying"
|
||||
rules={[{ required: true, message: intl.formatMessage({ id: 'login.captcha.placeholder' }) + '!' }]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'login.captcha.placeholder' }) + '!',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder={intl.formatMessage({ id: 'login.captcha.placeholder' })}
|
||||
@ -166,7 +173,7 @@ const LoginPage: React.FC = () => {
|
||||
prefix={null}
|
||||
suffix={
|
||||
<img
|
||||
src={`data:image/png;base64,${captchaImg}`}
|
||||
src={`data:image/png;base64,${captchaImg}`}
|
||||
alt="验证码"
|
||||
style={{ cursor: 'pointer', height: 32, verticalAlign: 'middle' }}
|
||||
onClick={fetchCaptcha}
|
||||
@ -176,7 +183,7 @@ const LoginPage: React.FC = () => {
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<div className='login-options'>
|
||||
<div className="login-options">
|
||||
<Form.Item name="remember" valuePropName="checked" noStyle>
|
||||
<Checkbox>{intl.formatMessage({ id: 'login.remember' })}</Checkbox>
|
||||
</Form.Item>
|
||||
@ -187,10 +194,16 @@ const LoginPage: React.FC = () => {
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit" className="login-form-button" loading={loading} size="large">
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
className="login-form-button"
|
||||
loading={loading}
|
||||
size="large"
|
||||
>
|
||||
{intl.formatMessage({ id: 'login.button' })}
|
||||
</Button>
|
||||
{activeKey !== 'accountLogin' && renderRegisterLink()}
|
||||
{renderRegisterLink()}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
@ -198,4 +211,4 @@ const LoginPage: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginPage;
|
||||
export default connect(({ user }: { user: UserModelState }) => ({ user }))(LoginPage);
|
||||
|
@ -37,5 +37,37 @@ export async function supplierLogin (data: API.LoginSupplier) {
|
||||
data
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
export async function getUserinfo() {
|
||||
return request('/v1/userinfo/get', {
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 退出
|
||||
*/
|
||||
export async function Logout() {
|
||||
return request('/v1/login/logout', {
|
||||
method: 'POST'
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 路由
|
||||
*/
|
||||
export async function findMenuList(data: any) {
|
||||
return request('/v1/menu/findMenuList', {
|
||||
method: 'POST',
|
||||
data
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 部门
|
||||
*/
|
||||
export async function queryUserOrgAll() {
|
||||
return request('/org/queryUserOrgAll', {
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
/**
|
||||
* request 网络请求工具
|
||||
* 更详细的 api 文档: https://github.com/umijs/umi-request
|
||||
* 更详细的 api 文档: https://github.com/umijs/umi-request
|
||||
*/
|
||||
import { extend } from 'umi-request';
|
||||
import { message } from 'antd';
|
||||
import { history } from 'umi';
|
||||
import { useUser } from '@/hooks/useUser';
|
||||
|
||||
const codeMessage = {
|
||||
200: '服务器成功返回请求的数据。',
|
||||
@ -24,6 +25,11 @@ const codeMessage = {
|
||||
504: '网关超时。',
|
||||
};
|
||||
|
||||
// 获取Token的函数
|
||||
const getToken = () => {
|
||||
return sessionStorage.getItem('token');
|
||||
};
|
||||
|
||||
/**
|
||||
* 异常处理程序
|
||||
*/
|
||||
@ -58,45 +64,28 @@ const request = extend({
|
||||
});
|
||||
// request拦截器, 改变url 或 options.
|
||||
request.interceptors.request.use((url, options) => {
|
||||
if (
|
||||
options.method === 'post' ||
|
||||
options.method === 'put' ||
|
||||
options.method === 'delete' ||
|
||||
options.method === 'get'
|
||||
) {
|
||||
//如果是获取token的url,则不加token
|
||||
// headers = {
|
||||
// Authorization: getUserToken() == null ? null : getUserToken(),
|
||||
// JwtToken: getSessionUserData() == null ? null : getSessionUserData().userId,
|
||||
// ...options.headers
|
||||
// }
|
||||
// options.headers = headers;
|
||||
}
|
||||
// 获取 token
|
||||
const token = sessionStorage.getItem('token');
|
||||
const userId = sessionStorage.getItem('userId');
|
||||
return {
|
||||
url: url,
|
||||
options: { ...options },
|
||||
url,
|
||||
options: {
|
||||
...options,
|
||||
headers: {
|
||||
...(options.headers || {}),
|
||||
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||||
...(userId ? { Mall3Check: `${userId}` } : {}),
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
//response拦截
|
||||
request.interceptors.response.use(async (response) => {
|
||||
const data = await response.clone().json();
|
||||
|
||||
//返回请求头状态码为401
|
||||
if (
|
||||
(response.status === 401 && data?.code == '90401') ||
|
||||
(response.status === 500 && data?.code == '90500')
|
||||
) {
|
||||
if ((response.status === 401) || (response.status === 500)) {
|
||||
history.replace({
|
||||
pathname: '/401',
|
||||
query: {
|
||||
code: '90401',
|
||||
},
|
||||
pathname: '/login',
|
||||
});
|
||||
} else {
|
||||
//2021.9.7 zhoujianlong 新增风险防控专用错误码4004
|
||||
if (data.code != undefined && data.code != '200' && data.code != '4004' && data.code !== '1') {
|
||||
message.error(data.message, 3);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
});
|
||||
|
@ -1,16 +1,15 @@
|
||||
import React from 'react';
|
||||
import { Redirect } from 'umi';
|
||||
import { message } from 'antd';
|
||||
import { useUser } from '@/hooks/useUser';
|
||||
import { connect, Redirect, history } from 'umi';
|
||||
import { message, Modal } from 'antd';
|
||||
// 权限校验
|
||||
export default (props: any) => {
|
||||
const { getToken } = useUser();
|
||||
if (getToken()) {
|
||||
|
||||
return <div>{props.children}</div>;
|
||||
const AuthWrapper = ({ user, children }: any) => {
|
||||
if (user.token) {
|
||||
return <div>{children}</div>;
|
||||
} else {
|
||||
// 提示后跳转
|
||||
message.error('请先登录');
|
||||
return <Redirect to="/login" />;
|
||||
}
|
||||
};
|
||||
|
||||
export default connect(({ user }: any) => ({
|
||||
user,
|
||||
}))(AuthWrapper);
|
||||
|
Reference in New Issue
Block a user