136 lines
3.2 KiB
TypeScript
136 lines
3.2 KiB
TypeScript
import { history, RunTimeLayoutConfig, useIntl } from '@umijs/max';
|
|
import { Dropdown } from 'antd';
|
|
import { handleRequestConfig as devRequestConfig } from '../config/request_dev';
|
|
import { handleRequestConfig as prodRequestConfig } from '../config/request_prod';
|
|
import UnAccessPage from './components/403/403Page';
|
|
|
|
import { ROUTE_LOGIN } from './constants';
|
|
import { parseJwt } from './utils/jwtTokenUtils';
|
|
import { getToken, removeToken } from './utils/localStorageUtils';
|
|
|
|
// Avatar component with i18n support
|
|
const AvatarDropdown = () => {
|
|
const intl = useIntl();
|
|
return (
|
|
<Dropdown
|
|
menu={{
|
|
items: [
|
|
{
|
|
key: 'logout',
|
|
label: intl.formatMessage({ id: 'common.logout' }),
|
|
onClick: () => {
|
|
removeToken();
|
|
history.push(ROUTE_LOGIN);
|
|
},
|
|
},
|
|
],
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
width: 32,
|
|
height: 32,
|
|
borderRadius: '50%',
|
|
cursor: 'pointer',
|
|
backgroundColor: '#1890ff',
|
|
color: 'white',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
fontWeight: 'bold',
|
|
}}
|
|
>
|
|
{intl.formatMessage({ id: 'common.user' })}
|
|
</div>
|
|
</Dropdown>
|
|
);
|
|
};
|
|
|
|
export async function getInitialState() {
|
|
const token: string = getToken();
|
|
const { pathname } = history.location;
|
|
|
|
if (!token) {
|
|
if (pathname !== ROUTE_LOGIN) {
|
|
history.push(`${ROUTE_LOGIN}?redirect=${pathname}`);
|
|
} else {
|
|
history.push(ROUTE_LOGIN);
|
|
}
|
|
return {};
|
|
}
|
|
|
|
const parsed = parseJwt(token);
|
|
if (!parsed) {
|
|
removeToken();
|
|
if (pathname !== ROUTE_LOGIN) {
|
|
history.push(`${ROUTE_LOGIN}?redirect=${pathname}`);
|
|
} else {
|
|
history.push(ROUTE_LOGIN);
|
|
}
|
|
return {};
|
|
}
|
|
|
|
const { sub, exp } = parsed;
|
|
const now = Math.floor(Date.now() / 1000);
|
|
const oneHour = 60 * 60;
|
|
|
|
if (exp - now < oneHour) {
|
|
console.warn('Token expired or nearly expired, redirecting...');
|
|
removeToken();
|
|
if (pathname !== ROUTE_LOGIN) {
|
|
history.push(`${ROUTE_LOGIN}?redirect=${pathname}`);
|
|
} else {
|
|
history.push(ROUTE_LOGIN);
|
|
}
|
|
return {};
|
|
}
|
|
|
|
return {
|
|
currentUser: sub,
|
|
exp,
|
|
};
|
|
}
|
|
|
|
export const layout: RunTimeLayoutConfig = (initialState) => {
|
|
return {
|
|
title: 'SMT Production Management',
|
|
fixedHeader: true,
|
|
contentWidth: 'Fluid',
|
|
navTheme: 'light',
|
|
splitMenus: true,
|
|
menu: {
|
|
locale: true,
|
|
},
|
|
contentStyle: {
|
|
padding: 0,
|
|
margin: 0,
|
|
paddingInline: 0,
|
|
},
|
|
avatarProps: {
|
|
size: 'small',
|
|
render: () => <AvatarDropdown />,
|
|
},
|
|
layout: 'top',
|
|
logout: () => {
|
|
removeToken();
|
|
history.push(ROUTE_LOGIN);
|
|
},
|
|
onPageChange: () => {
|
|
if (!initialState.initialState) {
|
|
history.push(ROUTE_LOGIN);
|
|
}
|
|
},
|
|
menuHeaderRender: undefined,
|
|
unAccessible: <UnAccessPage />,
|
|
token: {
|
|
pageContainer: {
|
|
paddingInlinePageContainerContent: 0,
|
|
paddingBlockPageContainerContent: 0,
|
|
},
|
|
},
|
|
};
|
|
};
|
|
|
|
const isProdBuild = process.env.NODE_ENV === 'production';
|
|
export const request = isProdBuild ? prodRequestConfig : devRequestConfig;
|