| 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 } 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) : true;  | 
|   });  | 
|   | 
|   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: 60000,  | 
|   // 前置守卫  | 
|   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;  | 
|     }  | 
|   ]  | 
| };  |