|  |  | 
 |  |  | import { outLogin } from '@/services/ant-design-pro/api'; | 
 |  |  | import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons'; | 
 |  |  | import { history, useModel } from '@umijs/max'; | 
 |  |  | import { Spin } from 'antd'; | 
 |  |  | import { createStyles } from 'antd-style'; | 
 |  |  | import { stringify } from 'querystring'; | 
 |  |  | import React, { useCallback } from 'react'; | 
 |  |  | import { flushSync } from 'react-dom'; | 
 |  |  | import HeaderDropdown from '../HeaderDropdown'; | 
 |  |  | import { setRemoteMenu } from '@/services/route' | 
 |  |  | import { removeToken } from '@/utils/token-util' | 
 |  |  |  | 
 |  |  | const useStyles = createStyles(({ token }) => { | 
 |  |  |   return { | 
 |  |  |     action: { | 
 |  |  |       display: 'flex', | 
 |  |  |       height: '48px', | 
 |  |  |       marginLeft: 'auto', | 
 |  |  |       overflow: 'hidden', | 
 |  |  |       alignItems: 'center', | 
 |  |  |       padding: '0 8px', | 
 |  |  |       cursor: 'pointer', | 
 |  |  |       borderRadius: token.borderRadius, | 
 |  |  |       '&:hover': { | 
 |  |  |         backgroundColor: token.colorBgTextHover, | 
 |  |  |       }, | 
 |  |  |     }, | 
 |  |  |   }; | 
 |  |  | }); | 
 |  |  |  | 
 |  |  | export const AvatarName = () => { | 
 |  |  |   const { initialState } = useModel('@@initialState'); | 
 |  |  |   const { currentUser } = initialState || {}; | 
 |  |  |   return <span className="anticon">{currentUser?.name}</span>; | 
 |  |  | }; | 
 |  |  |  | 
 |  |  | export const AvatarDropdown = ({ menu, children }) => { | 
 |  |  |   const { styles } = useStyles(); | 
 |  |  |   const { initialState, setInitialState } = useModel('@@initialState'); | 
 |  |  |  | 
 |  |  |   // 退出登录,并且将当前的 url 保存 | 
 |  |  |   const loginOut = async () => { | 
 |  |  |     // await outLogin(); | 
 |  |  |     removeToken(); | 
 |  |  |     setRemoteMenu(null); | 
 |  |  |     const { search, pathname } = window.location; | 
 |  |  |     const urlParams = new URL(window.location.href).searchParams; | 
 |  |  |     /** 此方法会跳转到 redirect 参数所在的位置 */ | 
 |  |  |     const redirect = urlParams.get('redirect'); | 
 |  |  |     // Note: There may be security issues, please note | 
 |  |  |     if (window.location.pathname !== '/user/login' && !redirect) { | 
 |  |  |       history.replace({ | 
 |  |  |         pathname: '/user/login', | 
 |  |  |         search: stringify({ | 
 |  |  |           redirect: pathname + search, | 
 |  |  |         }), | 
 |  |  |       }); | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  |  | 
 |  |  |   const onMenuClick = useCallback((event) => { | 
 |  |  |     const { key } = event; | 
 |  |  |     if (key === 'logout') { | 
 |  |  |       flushSync(() => { | 
 |  |  |         setInitialState((s) => ({ ...s, currentUser: undefined })); | 
 |  |  |       }); | 
 |  |  |       loginOut(); | 
 |  |  |       return; | 
 |  |  |     } | 
 |  |  |     history.push(`/user/${key}`); | 
 |  |  |   }, [setInitialState]); | 
 |  |  |  | 
 |  |  |   const loading = ( | 
 |  |  |     <span className={styles.action}> | 
 |  |  |       <Spin | 
 |  |  |         size="small" | 
 |  |  |         style={{ | 
 |  |  |           marginLeft: 8, | 
 |  |  |           marginRight: 8, | 
 |  |  |         }} | 
 |  |  |       /> | 
 |  |  |     </span> | 
 |  |  |   ); | 
 |  |  |  | 
 |  |  |   if (!initialState) { | 
 |  |  |     return loading; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   const { currentUser } = initialState; | 
 |  |  |  | 
 |  |  |   if (!currentUser || !currentUser.name) { | 
 |  |  |     return loading; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   const menuItems = [ | 
 |  |  |     // ...(menu | 
 |  |  |     //   ? [ | 
 |  |  |     //     { | 
 |  |  |     //       key: 'center', | 
 |  |  |     //       icon: <UserOutlined />, | 
 |  |  |     //       label: '个人中心', | 
 |  |  |     //     }, | 
 |  |  |     //     { | 
 |  |  |     //       key: 'settings', | 
 |  |  |     //       icon: <SettingOutlined />, | 
 |  |  |     //       label: '个人设置', | 
 |  |  |     //     }, | 
 |  |  |     //     { | 
 |  |  |     //       type: 'divider' as const, | 
 |  |  |     //     }, | 
 |  |  |     //   ] | 
 |  |  |     //   : []), | 
 |  |  |     { | 
 |  |  |       key: 'setting', | 
 |  |  |       icon: <SettingOutlined />, | 
 |  |  |       label: '个人设置', | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       type: 'divider' | 
 |  |  |     }, | 
 |  |  |     { | 
 |  |  |       key: 'logout', | 
 |  |  |       icon: <LogoutOutlined />, | 
 |  |  |       label: '退出登录', | 
 |  |  |     }, | 
 |  |  |   ]; | 
 |  |  |  | 
 |  |  |   return ( | 
 |  |  |     <HeaderDropdown | 
 |  |  |       menu={{ | 
 |  |  |         selectedKeys: [], | 
 |  |  |         onClick: onMenuClick, | 
 |  |  |         items: menuItems, | 
 |  |  |       }} | 
 |  |  |     > | 
 |  |  |       {children} | 
 |  |  |     </HeaderDropdown> | 
 |  |  |   ); | 
 |  |  | }; | 
 |  |  | import { outLogin } from '@/services/ant-design-pro/api';
 | 
 |  |  | import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
 | 
 |  |  | import { history, useModel } from '@umijs/max';
 | 
 |  |  | import { Spin } from 'antd';
 | 
 |  |  | import { createStyles } from 'antd-style';
 | 
 |  |  | import { stringify } from 'querystring';
 | 
 |  |  | import React, { useCallback } from 'react';
 | 
 |  |  | import { flushSync } from 'react-dom';
 | 
 |  |  | import HeaderDropdown from '../HeaderDropdown';
 | 
 |  |  | import { setRemoteMenu } from '@/services/route'
 | 
 |  |  | import { removeToken } from '@/utils/token-util'
 | 
 |  |  | 
 | 
 |  |  | const useStyles = createStyles(({ token }) => {
 | 
 |  |  |   return {
 | 
 |  |  |     action: {
 | 
 |  |  |       display: 'flex',
 | 
 |  |  |       height: '48px',
 | 
 |  |  |       marginLeft: 'auto',
 | 
 |  |  |       overflow: 'hidden',
 | 
 |  |  |       alignItems: 'center',
 | 
 |  |  |       padding: '0 8px',
 | 
 |  |  |       cursor: 'pointer',
 | 
 |  |  |       borderRadius: token.borderRadius,
 | 
 |  |  |       '&:hover': {
 | 
 |  |  |         backgroundColor: token.colorBgTextHover,
 | 
 |  |  |       },
 | 
 |  |  |     },
 | 
 |  |  |   };
 | 
 |  |  | });
 | 
 |  |  | 
 | 
 |  |  | export const AvatarName = () => {
 | 
 |  |  |   const { initialState } = useModel('@@initialState');
 | 
 |  |  |   const { currentUser } = initialState || {};
 | 
 |  |  |   return <span className="anticon">{currentUser?.name}</span>;
 | 
 |  |  | };
 | 
 |  |  | 
 | 
 |  |  | export const AvatarDropdown = ({ menu, children }) => {
 | 
 |  |  |   const { styles } = useStyles();
 | 
 |  |  |   const { initialState, setInitialState } = useModel('@@initialState');
 | 
 |  |  | 
 | 
 |  |  |   // 退出登录,并且将当前的 url 保存
 | 
 |  |  |   const loginOut = async () => {
 | 
 |  |  |     // await outLogin();
 | 
 |  |  |     removeToken();
 | 
 |  |  |     setRemoteMenu(null);
 | 
 |  |  |     const { search, pathname } = window.location;
 | 
 |  |  |     const urlParams = new URL(window.location.href).searchParams;
 | 
 |  |  |     /** 此方法会跳转到 redirect 参数所在的位置 */
 | 
 |  |  |     const redirect = urlParams.get('redirect');
 | 
 |  |  |     // Note: There may be security issues, please note
 | 
 |  |  |     if (window.location.pathname !== '/user/login' && !redirect) {
 | 
 |  |  |       history.replace({
 | 
 |  |  |         pathname: '/user/login',
 | 
 |  |  |         search: stringify({
 | 
 |  |  |           redirect: pathname + search,
 | 
 |  |  |         }),
 | 
 |  |  |       });
 | 
 |  |  |     }
 | 
 |  |  |   };
 | 
 |  |  | 
 | 
 |  |  |   const onMenuClick = useCallback((event) => {
 | 
 |  |  |     const { key } = event;
 | 
 |  |  |     if (key === 'logout') {
 | 
 |  |  |       flushSync(() => {
 | 
 |  |  |         setInitialState((s) => ({ ...s, currentUser: undefined }));
 | 
 |  |  |       });
 | 
 |  |  |       loginOut();
 | 
 |  |  |       return;
 | 
 |  |  |     }
 | 
 |  |  |     history.push(`/user/${key}`);
 | 
 |  |  |   }, [setInitialState]);
 | 
 |  |  | 
 | 
 |  |  |   const loading = (
 | 
 |  |  |     <span className={styles.action}>
 | 
 |  |  |       <Spin
 | 
 |  |  |         size="small"
 | 
 |  |  |         style={{
 | 
 |  |  |           marginLeft: 8,
 | 
 |  |  |           marginRight: 8,
 | 
 |  |  |         }}
 | 
 |  |  |       />
 | 
 |  |  |     </span>
 | 
 |  |  |   );
 | 
 |  |  | 
 | 
 |  |  |   if (!initialState) {
 | 
 |  |  |     return loading;
 | 
 |  |  |   }
 | 
 |  |  | 
 | 
 |  |  |   const { currentUser } = initialState;
 | 
 |  |  | 
 | 
 |  |  |   if (!currentUser || !currentUser.name) {
 | 
 |  |  |     return loading;
 | 
 |  |  |   }
 | 
 |  |  | 
 | 
 |  |  |   const menuItems = [
 | 
 |  |  |     // ...(menu
 | 
 |  |  |     //   ? [
 | 
 |  |  |     //     {
 | 
 |  |  |     //       key: 'center',
 | 
 |  |  |     //       icon: <UserOutlined />,
 | 
 |  |  |     //       label: '个人中心',
 | 
 |  |  |     //     },
 | 
 |  |  |     //     {
 | 
 |  |  |     //       key: 'settings',
 | 
 |  |  |     //       icon: <SettingOutlined />,
 | 
 |  |  |     //       label: '个人设置',
 | 
 |  |  |     //     },
 | 
 |  |  |     //     {
 | 
 |  |  |     //       type: 'divider' as const,
 | 
 |  |  |     //     },
 | 
 |  |  |     //   ]
 | 
 |  |  |     //   : []),
 | 
 |  |  |     // {
 | 
 |  |  |     //   type: 'divider'
 | 
 |  |  |     // },
 | 
 |  |  |     {
 | 
 |  |  |       key: 'logout',
 | 
 |  |  |       icon: <LogoutOutlined />,
 | 
 |  |  |       label: '退出登录',
 | 
 |  |  |     },
 | 
 |  |  |   ];
 | 
 |  |  | 
 | 
 |  |  |   return (
 | 
 |  |  |     <HeaderDropdown
 | 
 |  |  |       menu={{
 | 
 |  |  |         selectedKeys: [],
 | 
 |  |  |         onClick: onMenuClick,
 | 
 |  |  |         items: menuItems,
 | 
 |  |  |       }}
 | 
 |  |  |     >
 | 
 |  |  |       {children}
 | 
 |  |  |     </HeaderDropdown>
 | 
 |  |  |   );
 | 
 |  |  | };
 |