Merge pull request 'feat: 退出登录和token失效的处理' (#38) from dev-zw into dev

This commit is contained in:
cp3hnu 2024-04-28 08:49:39 +08:00
commit 701e97b006
17 changed files with 69 additions and 78 deletions

View File

@ -163,4 +163,5 @@ export default defineConfig({
},
javascriptEnabled: true,
},
// plugins: ['umi-plugin-keep-alive'],
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -133,22 +133,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
// 增加一个 loading 的状态
childrenRender: (children) => {
// if (initialState?.loading) return <PageLoading />;
return (
<>
{children}
{/* <SettingDrawer
disableUrlParams
enableDarkTheme
settings={initialState?.settings}
onSettingChange={(settings) => {
setInitialState((preInitialState) => ({
...preInitialState,
settings,
}));
}}
/> */}
</>
);
return <>{children}</>;
},
...initialState?.settings,
};

View File

@ -17,13 +17,8 @@ const HeaderDropdown: React.FC<HeaderDropdownProps> = ({ overlayClassName: cls,
},
};
});
return (
<Dropdown
overlayClassName={classNames(className, cls)}
getPopupContainer={(target) => target.parentElement || document.body}
{...restProps}
/>
);
return <Dropdown overlayClassName={classNames(className, cls)} {...restProps} />;
};
export default HeaderDropdown;

View File

@ -1,13 +1,12 @@
import { clearSessionToken } from '@/access';
import { PageEnum } from '@/enums/pagesEnums';
import { setRemoteMenu } from '@/services/session';
import { logout } from '@/services/system/auth';
import { gotoLoginPage } from '@/utils/ui';
import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
import { setAlpha } from '@ant-design/pro-components';
import { useEmotionCss } from '@ant-design/use-emotion-css';
import { history, useModel } from '@umijs/max';
import { Avatar, Spin } from 'antd';
import { stringify } from 'querystring';
import type { MenuInfo } from 'rc-menu/lib/interface';
import React, { useCallback } from 'react';
import { flushSync } from 'react-dom';
@ -23,7 +22,7 @@ const Name = () => {
const nameClassName = useEmotionCss(({ token }) => {
return {
width: '70px',
// width: '70px',
height: '48px',
overflow: 'hidden',
lineHeight: '48px',
@ -64,19 +63,7 @@ const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => {
await logout();
clearSessionToken();
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 !== PageEnum.LOGIN && !redirect) {
history.replace({
pathname: PageEnum.LOGIN,
search: stringify({
redirect: pathname + search,
}),
});
}
gotoLoginPage();
};
const actionClassName = useEmotionCss(({ token }) => {
return {

View File

@ -1,6 +1,5 @@
import { QuestionCircleOutlined } from '@ant-design/icons';
import { useEmotionCss } from '@ant-design/use-emotion-css';
import { SelectLang, useModel } from '@umijs/max';
import { useModel } from '@umijs/max';
import React from 'react';
import Avatar from './AvatarDropdown';
@ -17,21 +16,21 @@ const GlobalHeaderRight: React.FC = () => {
};
});
const actionClassName = useEmotionCss(({ token }) => {
return {
display: 'flex',
float: 'right',
height: '48px',
marginLeft: 'auto',
overflow: 'hidden',
cursor: 'pointer',
padding: '0 12px',
borderRadius: token.borderRadius,
'&:hover': {
backgroundColor: token.colorBgTextHover,
},
};
});
// const actionClassName = useEmotionCss(({ token }) => {
// return {
// display: 'flex',
// float: 'right',
// height: '48px',
// marginLeft: 'auto',
// overflow: 'hidden',
// cursor: 'pointer',
// padding: '0 12px',
// borderRadius: token.borderRadius,
// '&:hover': {
// backgroundColor: token.colorBgTextHover,
// },
// };
// });
const { initialState } = useModel('@@initialState');
@ -41,15 +40,15 @@ const GlobalHeaderRight: React.FC = () => {
return (
<div className={className}>
<span
{/* <span
className={actionClassName}
onClick={() => {
window.open('https://pro.ant.design/docs/getting-started');
}}
>
<QuestionCircleOutlined />
</span>
<Avatar menu={true} />
</span> */}
<Avatar menu={false} />
{/* <SelectLang className={actionClassName} /> */}
</div>
);

View File

@ -144,8 +144,15 @@ function AddExperimentModal({
label="实验描述"
name="description"
rules={[{ required: true, message: '请输入实验描述' }]}
style={{ marginBottom: '48px' }}
>
<Input placeholder="请输入实验描述" maxLength={128} showCount allowClear />
<Input.TextArea
placeholder="请输入实验描述"
maxLength={128}
autoSize={{ minRows: 2, maxRows: 5 }}
showCount
allowClear
/>
</Form.Item>
<Form.Item
label="选择流水线"

View File

@ -6,8 +6,8 @@
import type { RequestConfig } from '@umijs/max';
import { message } from 'antd';
import { clearSessionToken, getAccessToken, getRefreshToken, getTokenExpireTime } from './access';
const checkRegion = 5 * 60 * 1000;
import { setRemoteMenu } from './services/session';
import { gotoLoginPage } from './utils/ui';
/**
* Umi Max
@ -25,10 +25,8 @@ export const requestConfig: RequestConfig = {
if (expireTime) {
const left = Number(expireTime) - new Date().getTime();
const refreshToken = getRefreshToken();
if (left < checkRegion && refreshToken) {
if (left < 0) {
clearSessionToken();
}
if (left < 0 && refreshToken) {
clearSessionToken();
} else {
const accessToken = getAccessToken();
if (accessToken) {
@ -45,15 +43,19 @@ export const requestConfig: RequestConfig = {
responseInterceptors: [
(response: any) => {
const { status, data } = response;
// console.log('response', response);
if (status >= 200 && status < 300 && data && (data instanceof Blob || data.code === 200)) {
return response;
} else {
if (data && data.msg) {
message.error(data.msg);
if (status >= 200 && status < 300) {
if (data && (data instanceof Blob || data.code === 200)) {
return response;
} else if (data && data.code === 401) {
clearSessionToken();
setRemoteMenu(null);
gotoLoginPage(false);
} else {
message.error('请求失败');
message.error(data?.msg ?? '请求失败');
return Promise.reject(response);
}
} else {
message.error('请求失败');
return Promise.reject(response);
}
},

View File

@ -1,8 +1,7 @@
import { createIcon } from '@/utils/IconUtil';
import { MenuDataItem } from '@ant-design/pro-components';
import { request } from '@umijs/max';
import React, { lazy } from 'react';
import { createFromIconfontCN } from '@ant-design/icons';
let remoteMenu: any = null;
export function getRemoteMenu() {
@ -101,7 +100,7 @@ export function convertCompatRouters(childrens: API.RoutersMenuItem[]): any[] {
return {
path: item.path,
// icon:'icon-a-057_fenlei',
icon: 'icon-'+item.meta.icon,
icon: 'icon-' + item.meta.icon,
// icon: item.meta.icon,
name: item.meta.title,
routes: item.children ? convertCompatRouters(item.children) : undefined,

View File

@ -28,8 +28,8 @@ export async function login(body: API.LoginParams, options?: Record<string, any>
/** 退出登录接口 POST /api/login/outLogin */
export async function logout() {
return request<Record<string, any>>('/api/logout', {
method: 'delete',
return request<Record<string, any>>('/api/auth/logout', {
method: 'DELETE',
});
}

View File

@ -3,7 +3,9 @@
* @Date: 2024-04-19 14:42:51
* @Description: UI
*/
import { PageEnum } from '@/enums/pagesEnums';
import themes from '@/styles/theme.less';
import { history } from '@umijs/max';
import { Modal, type ModalFuncProps, type UploadFile } from 'antd';
// 自定义 Confirm 弹框
@ -43,3 +45,17 @@ export const getFileListFromEvent = (e: any) => {
return item;
});
};
// 去登录页面
export const gotoLoginPage = (toHome: boolean = true) => {
const { search, pathname } = window.location;
const urlParams = new URLSearchParams();
urlParams.append('redirect', pathname + search);
const newSearch = toHome ? '' : urlParams.toString();
if (window.location.pathname !== PageEnum.LOGIN) {
history.replace({
pathname: PageEnum.LOGIN,
search: newSearch,
});
}
};