2024-03-26 11:47:11 +08:00
import type { AxiosResponse } from 'axios' ;
2024-06-07 11:32:38 +08:00
import { createFlatRequest } from '@sa/axios' ;
2024-03-26 11:47:11 +08:00
import { useAuthStore } from '@/store/modules/auth' ;
2024-05-08 11:57:58 +08:00
import { $t } from '@/locales' ;
2024-03-08 17:59:45 +08:00
import { localStg } from '@/utils/storage' ;
2024-03-21 10:57:53 +08:00
import { getServiceBaseURL } from '@/utils/service' ;
2024-05-08 11:57:58 +08:00
import { handleRefreshToken , showErrorMsg } from './shared' ;
import type { RequestInstanceState } from './type' ;
2024-03-08 17:59:45 +08:00
2024-03-21 10:57:53 +08:00
const isHttpProxy = import . meta . env . DEV && import . meta . env . VITE_HTTP_PROXY === 'Y' ;
2024-06-07 10:20:29 +08:00
const { baseURL } = getServiceBaseURL ( import . meta . env , isHttpProxy ) ;
2024-03-08 17:59:45 +08:00
2024-05-08 11:57:58 +08:00
export const request = createFlatRequest < App.Service.Response , RequestInstanceState > (
2024-03-08 17:59:45 +08:00
{
2024-03-21 10:57:53 +08:00
baseURL ,
2024-03-26 11:47:11 +08:00
headers : {
timeout : 6000
}
2024-03-08 17:59:45 +08:00
} ,
{
async onRequest ( config ) {
const { headers } = config ;
// set token
const token = localStg . get ( 'token' ) ;
2024-03-21 11:53:27 +08:00
const namespaceId = localStg . get ( 'namespaceId' ) ;
// const Authorization = token ? `Bearer ${token}` : null;
2024-04-16 22:54:19 +08:00
headers [ 'SNAIL-JOB-AUTH' ] = token ;
headers [ 'SNAIL-JOB-NAMESPACE-ID' ] = namespaceId ;
Object . assign ( headers , { 'SNAIL-JOB-AUTH' : token , 'SNAIL-JOB-NAMESPACE-ID' : namespaceId } ) ;
2024-03-08 17:59:45 +08:00
return config ;
} ,
isBackendSuccess ( response ) {
2024-03-26 11:47:11 +08:00
// when the backend response code is "0000"(default), it means the request is success
// to change this logic by yourself, you can modify the `VITE_SERVICE_SUCCESS_CODE` in `.env` file
2024-05-08 11:57:58 +08:00
return String ( response . data . status ) === import . meta . env . VITE_SERVICE_SUCCESS_CODE ;
2024-03-08 17:59:45 +08:00
} ,
2024-03-26 11:47:11 +08:00
async onBackendFail ( response , instance ) {
const authStore = useAuthStore ( ) ;
function handleLogout() {
authStore . resetStore ( ) ;
}
function logoutAndCleanup() {
handleLogout ( ) ;
window . removeEventListener ( 'beforeunload' , handleLogout ) ;
2024-05-08 11:57:58 +08:00
request . state . errMsgStack = request . state . errMsgStack . filter ( msg = > msg !== response . data . message ) ;
2024-03-26 11:47:11 +08:00
}
// 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 ( ',' ) || [ ] ;
2024-06-15 10:39:12 +08:00
if ( logoutCodes . includes ( response . data . status ? . toString ( ) ) ) {
2024-03-26 11:47:11 +08:00
handleLogout ( ) ;
return null ;
}
// 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 ( ',' ) || [ ] ;
2024-06-15 10:39:12 +08:00
if ( modalLogoutCodes . includes ( response . data . status ? . toString ( ) ) ) {
2024-05-08 11:57:58 +08:00
request . state . errMsgStack = [ . . . ( request . state . errMsgStack || [ ] ) , response . data . message ] ;
2024-03-26 11:47:11 +08:00
// prevent the user from refreshing the page
window . addEventListener ( 'beforeunload' , handleLogout ) ;
2024-03-28 16:22:18 +08:00
// prevent repeated pop-ups
if ( ! request . state . isLogout ) {
request . state . isLogout = true ;
window . $dialog ? . error ( {
title : 'Error' ,
2024-06-07 10:20:29 +08:00
content : $t ( 'request.logoutWithModalMsg' ) ,
2024-03-28 16:22:18 +08:00
positiveText : $t ( 'common.confirm' ) ,
maskClosable : false ,
2024-06-07 11:24:30 +08:00
closeOnEsc : false ,
2024-03-28 16:22:18 +08:00
onPositiveClick() {
request . state . isLogout = false ;
logoutAndCleanup ( ) ;
} ,
onClose() {
request . state . isLogout = false ;
logoutAndCleanup ( ) ;
}
} ) ;
}
2024-03-26 11:47:11 +08:00
return null ;
}
// 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`
const expiredTokenCodes = import . meta . env . VITE_SERVICE_EXPIRED_TOKEN_CODES ? . split ( ',' ) || [ ] ;
2024-05-08 11:57:58 +08:00
if ( expiredTokenCodes . includes ( response . data . status ) && ! request . state . isRefreshingToken ) {
2024-03-26 11:47:11 +08:00
request . state . isRefreshingToken = true ;
const refreshConfig = await handleRefreshToken ( response . config ) ;
request . state . isRefreshingToken = false ;
if ( refreshConfig ) {
return instance . request ( refreshConfig ) as Promise < AxiosResponse > ;
}
}
return null ;
2024-03-08 17:59:45 +08:00
} ,
transformBackendResponse ( response ) {
2024-03-30 17:07:04 +08:00
return response . data . total ? response.data : response.data.data ;
2024-03-08 17:59:45 +08:00
} ,
onError ( error ) {
// when the request is fail, you can show error message
let message = error . message ;
2024-03-26 11:47:11 +08:00
let backendErrorCode = '' ;
2024-03-08 17:59:45 +08:00
2024-03-26 11:47:11 +08:00
// get backend error message and code
2024-06-07 11:32:38 +08:00
message = error . response ? . data ? . message || message ;
2024-06-15 10:39:12 +08:00
backendErrorCode = error . response ? . data ? . status ? . toString ( ) || '' ;
2024-03-26 11:47:11 +08:00
// the error message is displayed in the modal
const modalLogoutCodes = import . meta . env . VITE_SERVICE_MODAL_LOGOUT_CODES ? . split ( ',' ) || [ ] ;
if ( modalLogoutCodes . includes ( backendErrorCode ) ) {
return ;
}
// when the token is expired, refresh token and retry request, so no need to show error message
const expiredTokenCodes = import . meta . env . VITE_SERVICE_EXPIRED_TOKEN_CODES ? . split ( ',' ) || [ ] ;
if ( expiredTokenCodes . includes ( backendErrorCode ) ) {
return ;
2024-03-08 17:59:45 +08:00
}
2024-05-08 11:57:58 +08:00
showErrorMsg ( request . state , message ) ;
2024-03-08 17:59:45 +08:00
}
}
) ;