feat(project): base smatec's frontend
This commit is contained in:
153
src/app.tsx
Normal file
153
src/app.tsx
Normal file
@@ -0,0 +1,153 @@
|
||||
// 运行时配置
|
||||
|
||||
import { getLocale, history, Link, RunTimeLayoutConfig } from '@umijs/max';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import { handleRequestConfig as devRequestConfig } from '../config/request_dev';
|
||||
import { handleRequestConfig as prodRequestConfig } from '../config/request_prod';
|
||||
import { AvatarDropdown } from './components/Avatar/AvatarDropdown';
|
||||
import IconFont from './components/IconFont';
|
||||
import LanguageSwitcher from './components/Lang/LanguageSwitcher';
|
||||
import ThemeProvider from './components/Theme/ThemeProvider';
|
||||
import ThemeSwitcher from './components/Theme/ThemeSwitcher';
|
||||
import { THEME_KEY } from './constants';
|
||||
import { ROUTE_LOGIN } from './constants/routes';
|
||||
import NotFoundPage from './pages/Exception/NotFound';
|
||||
import UnAccessPage from './pages/Exception/UnAccess';
|
||||
import { apiQueryProfile } from './services/master/AuthController';
|
||||
import { checkTokenExpired } from './utils/jwt';
|
||||
import { getLogoImage } from './utils/logo';
|
||||
import {
|
||||
clearAllData,
|
||||
clearSessionData,
|
||||
getToken,
|
||||
removeToken,
|
||||
} from './utils/storage';
|
||||
const isProdBuild = process.env.NODE_ENV === 'production';
|
||||
export type InitialStateResponse = {
|
||||
getUserProfile?: () => Promise<MasterModel.ProfileResponse | undefined>;
|
||||
currentUserProfile?: MasterModel.ProfileResponse;
|
||||
theme?: 'light' | 'dark';
|
||||
};
|
||||
|
||||
// 全局初始化数据配置,用于 Layout 用户信息和权限初始化
|
||||
// 更多信息见文档:https://umijs.org/docs/api/runtime-config#getinitialstate
|
||||
export async function getInitialState(): Promise<InitialStateResponse> {
|
||||
const userToken: string = getToken();
|
||||
const { pathname } = history.location;
|
||||
|
||||
dayjs.locale(getLocale() === 'en-US' ? 'en' : 'vi');
|
||||
if (!userToken) {
|
||||
if (pathname !== ROUTE_LOGIN) {
|
||||
history.push(`${ROUTE_LOGIN}?redirect=${pathname}`);
|
||||
} else {
|
||||
history.push(ROUTE_LOGIN);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
const isTokenExpried = checkTokenExpired(userToken);
|
||||
if (isTokenExpried) {
|
||||
removeToken();
|
||||
clearAllData();
|
||||
clearSessionData();
|
||||
window.location.href = ROUTE_LOGIN;
|
||||
return {};
|
||||
}
|
||||
|
||||
const getUserProfile = async () => {
|
||||
try {
|
||||
const resp = await apiQueryProfile();
|
||||
return resp;
|
||||
} catch (error) {
|
||||
removeToken();
|
||||
clearAllData();
|
||||
clearSessionData();
|
||||
window.location.href = ROUTE_LOGIN;
|
||||
}
|
||||
};
|
||||
const resp = await getUserProfile();
|
||||
const currentTheme =
|
||||
(localStorage.getItem(THEME_KEY) as 'light' | 'dark') || 'light';
|
||||
return {
|
||||
getUserProfile: getUserProfile!,
|
||||
currentUserProfile: resp,
|
||||
theme: currentTheme,
|
||||
};
|
||||
}
|
||||
|
||||
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
|
||||
const isDark = initialState?.theme === 'dark';
|
||||
return {
|
||||
logo: getLogoImage(),
|
||||
menu: {
|
||||
locale: true,
|
||||
},
|
||||
fixedHeader: true,
|
||||
contentWidth: 'Fluid',
|
||||
navTheme: isDark ? 'realDark' : 'light',
|
||||
splitMenus: true,
|
||||
iconfontUrl: '//at.alicdn.com/t/c/font_5096559_y5mqyqd86f.js',
|
||||
contentStyle: {
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
paddingInline: 0,
|
||||
},
|
||||
actionsRender: () => [
|
||||
<ThemeSwitcher key="theme-switcher" />,
|
||||
<LanguageSwitcher key="lang-switcher" type="dropdown" />,
|
||||
],
|
||||
avatarProps: {
|
||||
size: 'small',
|
||||
src: '/avatar.svg',
|
||||
render: () => (
|
||||
<AvatarDropdown currentUserProfile={initialState?.currentUserProfile} />
|
||||
),
|
||||
},
|
||||
childrenRender: (children) => {
|
||||
return (
|
||||
<ThemeProvider>
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
components: {
|
||||
Collapse: {
|
||||
contentPadding: '0px',
|
||||
borderlessContentPadding: '0px',
|
||||
headerPadding: '0px',
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ConfigProvider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
},
|
||||
layout: 'top',
|
||||
menuHeaderRender: undefined,
|
||||
menuItemRender: (item, dom) => {
|
||||
if (item.path) {
|
||||
// Coerce values to string to satisfy TypeScript expectations
|
||||
const to = String(item.path ?? '');
|
||||
const iconType = String(item.icon ?? '');
|
||||
const label = String(item.name ?? '');
|
||||
return (
|
||||
<Link to={to}>
|
||||
<IconFont type={iconType} />
|
||||
<span>{label}</span>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
return dom;
|
||||
},
|
||||
token: {
|
||||
header: {
|
||||
colorBgMenuItemSelected: '#EEF7FF', // background khi chọn
|
||||
colorTextMenuSelected: isDark ? '#fff' : '#1A2130', // màu chữ khi chọn
|
||||
},
|
||||
},
|
||||
unAccessible: <UnAccessPage />,
|
||||
noFound: <NotFoundPage />,
|
||||
};
|
||||
};
|
||||
|
||||
export const request = isProdBuild ? prodRequestConfig : devRequestConfig;
|
||||
Reference in New Issue
Block a user