mirror of
https://github.com/chansee97/nova-admin.git
synced 2026-07-12 05:51:13 +08:00
101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
import { local } from '@/utils'
|
||
import { createAlova } from 'alova'
|
||
import { createServerTokenAuthentication } from 'alova/client'
|
||
import adapterFetch from 'alova/fetch'
|
||
import VueHook from 'alova/vue'
|
||
import type { VueHookType } from 'alova/vue'
|
||
import {
|
||
DEFAULT_ALOVA_OPTIONS,
|
||
DEFAULT_BACKEND_OPTIONS,
|
||
} from './config'
|
||
import {
|
||
handleBusinessError,
|
||
handleRefreshToken,
|
||
handleResponseError,
|
||
handleServiceResult,
|
||
} from './handle'
|
||
|
||
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication<VueHookType>({
|
||
// 服务端判定token过期
|
||
refreshTokenOnSuccess: {
|
||
// 当服务端返回401时,表示token过期
|
||
isExpired: (response, method) => {
|
||
const isExpired = method.meta && method.meta.isExpired
|
||
return response.status === 401 && !isExpired
|
||
},
|
||
|
||
// 当token过期时触发,在此函数中触发刷新token
|
||
handler: async (_response, method) => {
|
||
// 此处采取限制,防止过期请求无限循环重发
|
||
if (!method.meta)
|
||
method.meta = { isExpired: true }
|
||
else
|
||
method.meta.isExpired = true
|
||
|
||
await handleRefreshToken()
|
||
},
|
||
},
|
||
// 添加token到请求头
|
||
assignToken: (method) => {
|
||
method.config.headers.Authorization = `Bearer ${local.get('accessToken')}`
|
||
},
|
||
})
|
||
|
||
// docs path of alova.js https://alova.js.org/
|
||
export function createAlovaInstance(
|
||
alovaConfig: Service.AlovaConfig,
|
||
backendConfig?: Service.BackendConfig,
|
||
) {
|
||
const _backendConfig = { ...DEFAULT_BACKEND_OPTIONS, ...backendConfig }
|
||
const _alovaConfig = { ...DEFAULT_ALOVA_OPTIONS, ...alovaConfig }
|
||
|
||
return createAlova({
|
||
statesHook: VueHook,
|
||
requestAdapter: adapterFetch(),
|
||
cacheFor: null,
|
||
baseURL: _alovaConfig.baseURL,
|
||
timeout: _alovaConfig.timeout,
|
||
|
||
beforeRequest: onAuthRequired((method) => {
|
||
if (method.meta?.isFormPost) {
|
||
method.config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
||
method.data = new URLSearchParams(method.data as URLSearchParams).toString()
|
||
}
|
||
alovaConfig.beforeRequest?.(method)
|
||
}),
|
||
responded: onResponseRefreshToken({
|
||
// 请求成功的拦截器
|
||
onSuccess: async (response, method) => {
|
||
const { status } = response
|
||
|
||
if (status === 200) {
|
||
// 返回blob数据
|
||
if (method.meta?.isBlob)
|
||
return response.blob()
|
||
|
||
// 返回json数据
|
||
const apiData = await response.json()
|
||
// 请求成功
|
||
if (apiData[_backendConfig.codeKey] === _backendConfig.successCode)
|
||
return handleServiceResult(apiData)
|
||
|
||
// 业务请求失败
|
||
const errorResult = handleBusinessError(apiData, _backendConfig)
|
||
return handleServiceResult(errorResult, false)
|
||
}
|
||
// 接口请求失败
|
||
const errorResult = handleResponseError(response)
|
||
return handleServiceResult(errorResult, false)
|
||
},
|
||
onError: (error, method) => {
|
||
const tip = `[${method.type}] - [${method.url}] - ${error.message}`
|
||
window.$message?.warning(tip)
|
||
},
|
||
|
||
onComplete: async (_method) => {
|
||
// 处理请求完成逻辑
|
||
},
|
||
}),
|
||
})
|
||
}
|