import React from 'react';
|
import { Footer, Question, SelectLang, AvatarDropdown, AvatarName, Brightness, LayoutSwitch, FullScreen } from '@/components';
|
import { LinkOutlined } from '@ant-design/icons';
|
import { SettingDrawer } from '@ant-design/pro-components';
|
import { history, Link } from '@umijs/max';
|
import defaultSettings from '../config/defaultSettings';
|
import { errorConfig } from './requestErrorConfig';
|
import { getRemoteMenu, getRoutersInfo, getUserInfo, setRemoteMenu, patchRouteWithRemoteMenus } from './services/route';
|
import { getToken, setToken } from '@/utils/token-util'
|
import { TOKEN_HEADER_NAME, TOKEN_STORE_NAME } from '@/config/setting';
|
import { API_BASE_URL, API_TIMEOUT } from '@/config/setting'
|
import { message } from 'antd';
|
|
import logo from '../public/img/logo.png'
|
import logoDark from '../public/img/logo-dark.png'
|
|
const isDev = process.env.NODE_ENV === 'development';
|
const loginPath = '/user/login';
|
const defaultAvatar = 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png'
|
|
// https://xflow.antv.vision/zh-CN/docs/tutorial/solutions/dag DAG 流程图
|
export function render(oldRender) {
|
const token = getToken();
|
if (!token || token?.length === 0) {
|
oldRender();
|
return;
|
}
|
getRoutersInfo().then(res => {
|
setRemoteMenu(res);
|
oldRender();
|
});
|
}
|
|
export async function patchClientRoutes({ routes }) {
|
patchRouteWithRemoteMenus(routes);
|
}
|
|
export async function onRouteChange({ clientRoutes, location }) {
|
const menus = getRemoteMenu();
|
if (menus === null && location.pathname !== loginPath) {
|
history.go(0);
|
}
|
}
|
|
/**
|
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
|
* */
|
export async function getInitialState() {
|
const fetchUserInfo = async () => {
|
try {
|
const { data: userInfo } = await getUserInfo({
|
skipErrorHandler: true,
|
});
|
if (userInfo?.avatar === '') {
|
userInfo.avatar = defaultAvatar;
|
}
|
userInfo.name = userInfo.nickname;
|
return {
|
...userInfo
|
};
|
} catch (error) {
|
console.log(error);
|
history.push(loginPath);
|
}
|
return undefined;
|
};
|
// 如果不是登录页面,执行
|
const { location } = history;
|
if (location.pathname !== loginPath) {
|
const currentUser = await fetchUserInfo();
|
return {
|
fetchUserInfo,
|
currentUser,
|
settings: defaultSettings,
|
};
|
}
|
return {
|
memo: 'create by vincent',
|
fetchUserInfo,
|
settings: defaultSettings,
|
};
|
}
|
|
// ProLayout 支持的api https://procomponents.ant.design/components/layout
|
// 优先级 layout > config > defaultSetting
|
export const layout = ({ initialState, setInitialState }) => {
|
const [darkMode, setDarkMode] = React.useState(() => {
|
const storedValue = localStorage.getItem('darkMode');
|
return storedValue !== null ? JSON.parse(storedValue) : false;
|
});
|
|
const [layoutMode, setLayoutMode] = React.useState(() => {
|
const storedValue = localStorage.getItem('layoutMode');
|
return storedValue !== null ? JSON.parse(storedValue) : true;
|
});
|
|
const [fullScreen, setFullScreen] = React.useState(false);
|
|
React.useEffect(() => {
|
localStorage.setItem('darkMode', JSON.stringify(darkMode));
|
localStorage.setItem('layoutMode', JSON.stringify(layoutMode));
|
}, [darkMode, layoutMode]);
|
|
return {
|
actionsRender: () => [
|
// <Question key="doc" />,
|
<SelectLang key="SelectLang" />,
|
<FullScreen fullScreen={fullScreen} setFullScreen={setFullScreen} />,
|
<LayoutSwitch layoutMode={layoutMode} setLayoutMode={setLayoutMode} />,
|
<Brightness darkMode={darkMode} setDarkMode={setDarkMode} />,
|
],
|
avatarProps: {
|
src: initialState?.currentUser?.avatar,
|
title: <AvatarName />,
|
render: (_, avatarChildren) => {
|
return <AvatarDropdown>{avatarChildren}</AvatarDropdown>;
|
},
|
},
|
menu: {
|
locale: false,
|
// 每当 initialState?.currentUser?.userid 发生修改时重新执行 request
|
params: {
|
userId: initialState?.currentUser?.id,
|
},
|
request: async () => {
|
if (!initialState?.currentUser?.id) {
|
return [];
|
}
|
return getRemoteMenu();
|
},
|
},
|
footerRender: () => <Footer />,
|
onPageChange: () => {
|
const { location } = history;
|
// 如果没有登录,重定向到 login
|
if (!initialState?.currentUser && location.pathname !== loginPath) {
|
history.push(loginPath);
|
}
|
},
|
// token: {
|
// bgLayout: '#fff',
|
// header: {
|
// colorBgHeader: '#fff',
|
// },
|
// sider: {
|
// colorMenuBackground: '#fff',
|
// },
|
// pageContainer: {
|
// colorBgPageContainer: '#fff',
|
// },
|
// },
|
bgLayoutImgList: [
|
// {
|
// src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr',
|
// left: 85,
|
// bottom: 100,
|
// height: '303px',
|
// },
|
// {
|
// src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr',
|
// bottom: -68,
|
// right: -45,
|
// height: '303px',
|
// },
|
// {
|
// src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr',
|
// bottom: 0,
|
// left: 0,
|
// width: '331px',
|
// },
|
],
|
// 显示在菜单右下角的快捷操作
|
links: [],
|
menuHeaderRender: undefined,
|
// 自定义 403 页面
|
// unAccessible: <div>unAccessible</div>,
|
// 增加一个 loading 的状态
|
childrenRender: (children) => {
|
// if (initialState?.loading) return <PageLoading />;
|
return (
|
<>
|
{children}
|
{/* {isDev && (
|
<SettingDrawer
|
disableUrlParams
|
enableDarkTheme
|
settings={initialState?.settings}
|
onSettingChange={(settings) => {
|
console.log(settings);
|
setInitialState((preInitialState) => ({
|
...preInitialState,
|
settings,
|
}));
|
}}
|
/>
|
)} */}
|
</>
|
);
|
},
|
...initialState?.settings,
|
layout: layoutMode ? 'top' : 'mix', // layout 的菜单模式,side:右侧导航,top:顶部导航
|
// contentStyle: () => { // layout 的内容区 style
|
// return
|
// },
|
contentWidth: 'Fluid', // layout 的内容模式,Fluid:自适应(全屏),Fixed:定宽 (小) 1200px
|
fixedHeader: true, // 固定 header
|
fixSiderbar: true, // 固定导航
|
// settings: defaultSettings, // layout 的设置
|
// waterMarkProps: { content: initialState?.currentUser?.nickname }, //水印
|
// navTheme: 'realDark', // 默认主题颜色 "realDark" | "light" | undef...
|
navTheme: darkMode ? 'realDark' : 'light',
|
footerRender: false, // 页脚 启用请注释,不是设置为true
|
logo: darkMode
|
? <img src={logo} className='header-logo' />
|
: <img src={logoDark} className='header-logo' />
|
,
|
title: (
|
<div className='header-title'>
|
</div>
|
),
|
colorWeak: true,
|
};
|
};
|
|
|
/**
|
* @name request 配置,可以配置错误处理
|
* 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
|
* @doc https://umijs.org/docs/max/request#配置
|
*/
|
export const request = {
|
baseURL: API_BASE_URL,
|
...errorConfig,
|
timeout: API_TIMEOUT * 1000,
|
// 前置守卫
|
requestInterceptors: [
|
(url, options) => {
|
const token = getToken();
|
if (token && options.headers) {
|
options.headers[TOKEN_HEADER_NAME] = token;
|
}
|
return { url, options };
|
}
|
],
|
// 后置守卫
|
responseInterceptors: [
|
(response) => {
|
if (response?.data?.code === 401) {
|
// message.error(intl.formatMessage({
|
// id: 'pages.login.failure',
|
// defaultMessage: '登录失败,请重试!',
|
// }));
|
history.push(loginPath)
|
}
|
const token = response.headers[TOKEN_HEADER_NAME];
|
if (token) {
|
setToken(token);
|
}
|
return response;
|
}
|
]
|
};
|