feat(projects): Blocking subsequent business codes during request processing of backend codes (#506)

This commit is contained in:
Ma.Jinkai 2024-06-18 09:47:34 +08:00
parent 47bc8d770d
commit a13251efd0
4 changed files with 39 additions and 26 deletions

View File

@ -46,6 +46,8 @@ const local: App.I18n.Schema = {
yes: 'Yes', yes: 'Yes',
no: 'No' no: 'No'
}, },
reLogin: 'Go to login',
tryAgain: 'Try again',
messageLevel: { messageLevel: {
success: 'Success', success: 'Success',
error: 'Error', error: 'Error',

View File

@ -46,6 +46,8 @@ const local: App.I18n.Schema = {
yes: '是', yes: '是',
no: '否' no: '否'
}, },
reLogin: '重新登录',
tryAgain: '我再试试',
messageLevel: { messageLevel: {
success: '成功', success: '成功',
error: '错误', error: '错误',

View File

@ -36,53 +36,60 @@ export const request = createFlatRequest<App.Service.Response, RequestInstanceSt
async onBackendFail(response, instance) { async onBackendFail(response, instance) {
const authStore = useAuthStore(); const authStore = useAuthStore();
function handleLogout() { async function handleLogout() {
authStore.resetStore(); await authStore.resetStore();
} }
function logoutAndCleanup() { function cleanup() {
handleLogout();
window.removeEventListener('beforeunload', handleLogout); window.removeEventListener('beforeunload', handleLogout);
request.state.errMsgStack = request.state.errMsgStack.filter(msg => msg !== response.data.msg); request.state.errMsgStack = request.state.errMsgStack.filter(msg => msg !== response.data.msg);
} }
async function cleanupAndLogout() {
cleanup();
await handleLogout();
}
// when the backend response code is in `logoutCodes`, it means the user will be logged out and redirected to login page // when the backend response code is in `logoutCodes`, it means the user will be logged out and redirected to login page
const logoutCodes = import.meta.env.VITE_SERVICE_LOGOUT_CODES?.split(',') || []; const logoutCodes = import.meta.env.VITE_SERVICE_LOGOUT_CODES?.split(',');
if (logoutCodes.includes(response.data.code)) { if (logoutCodes?.includes(response.data.code)) {
handleLogout(); await handleLogout();
return null; return null;
} }
// when the backend response code is in `modalLogoutCodes`, it means the user will be logged out by displaying a modal // when the backend response code is in `modalLogoutCodes`, it means the user will be logged out by displaying a modal
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || []; const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',');
if (modalLogoutCodes.includes(response.data.code) && !request.state.errMsgStack?.includes(response.data.msg)) { if (modalLogoutCodes?.includes(response.data.code) && !request.state.errMsgStack?.includes(response.data.msg)) {
request.state.errMsgStack = [...(request.state.errMsgStack || []), response.data.msg]; request.state.errMsgStack = [...(request.state.errMsgStack || []), response.data.msg];
// prevent the user from refreshing the page // prevent the user from refreshing the page
window.addEventListener('beforeunload', handleLogout); window.addEventListener('beforeunload', handleLogout);
return new Promise<AxiosResponse | null>((resolve, _reject) => {
window.$dialog?.error({ window.$dialog?.error({
title: $t('common.messageLevel.error'), title: $t('common.messageLevel.error'),
content: response.data.msg, content: response.data.msg,
positiveText: $t('common.confirm'), positiveText: $t('common.reLogin'),
negativeText: $t('common.tryAgain'),
closable: false,
maskClosable: false, maskClosable: false,
closeOnEsc: false, closeOnEsc: false,
onPositiveClick() { autoFocus: false,
logoutAndCleanup(); onPositiveClick: async () => {
await cleanupAndLogout();
}, },
onClose() { onClose() {
logoutAndCleanup(); cleanup();
resolve(null);
} }
}); });
});
return null;
} }
// when the backend response code is in `expiredTokenCodes`, it means the token is expired, and refresh token // when the backend response code is in `expiredTokenCodes`, it means the token is expired, and refresh token
// the api `refreshToken` can not return error code in `expiredTokenCodes`, otherwise it will be a dead loop, should return `logoutCodes` or `modalLogoutCodes` // the api `refreshToken` can not return error code in `expiredTokenCodes`, otherwise it will be a dead loop, should return `logoutCodes` or `modalLogoutCodes`
const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || []; const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',');
if (expiredTokenCodes.includes(response.data.code) && !request.state.isRefreshingToken) { if (expiredTokenCodes?.includes(response.data.code) && !request.state.isRefreshingToken) {
request.state.isRefreshingToken = true; request.state.isRefreshingToken = true;
const refreshConfig = await handleRefreshToken(response.config); const refreshConfig = await handleRefreshToken(response.config);

View File

@ -296,6 +296,8 @@ declare namespace App {
yes: string; yes: string;
no: string; no: string;
}; };
reLogin: string;
tryAgain: string;
messageLevel: { messageLevel: {
success: string; success: string;
error: string; error: string;