You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
besure_app/src/utils/request.ts

208 lines
5.6 KiB
TypeScript

import config from '@/config'
import { getToken, getRefreshToken, removeToken, setToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { toast, tansParams } from '@/utils/common'
import { RequestConfig, ResponseData } from '@/types/request'
import modal from '@/plugins/modal'
let timeout = 300000
let isRefreshToken = false
let isRelogin = false
let requestList: Array<{
config: RequestConfig
resolve: (value: ResponseData<any>) => void
reject: (reason?: any) => void
}> = []
export const SERVER_BASE_URL_STORAGE_KEY = 'serverBaseUrl'
export function getBaseUrl() {
return uni.getStorageSync(SERVER_BASE_URL_STORAGE_KEY) || config.baseUrl
}
function prepareConfig(config: RequestConfig): RequestConfig {
const requestConfig: RequestConfig = {
...config,
header: {
...(config.header || {})
}
}
const isToken = (requestConfig.headers || {}).isToken === false
requestConfig.header!['tenantId'] = '1'
if (getToken() && !isToken) {
requestConfig.header!['Authorization'] = 'Bearer ' + getToken()
}
const method = (requestConfig.method || 'GET').toUpperCase()
if ((method === 'POST' || method === 'PUT') && requestConfig.data) {
requestConfig.header!['Content-Type'] = 'application/json'
}
if (requestConfig.params) {
let url = requestConfig.url + '?' + tansParams(requestConfig.params)
url = url.slice(0, -1)
requestConfig.url = url
}
return requestConfig
}
function handleRequestError(error: any) {
let { message } = error
if (message === 'Network Error') {
message = '后端接口连接异常'
} else if (message && message.includes('timeout')) {
message = '系统接口请求超时'
} else if (message && message.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}
toast(message)
}
function handleAuthorized() {
if (!isRelogin) {
isRelogin = true
removeToken()
uni.reLaunch({
url: '/pages/login',
complete: () => {
isRelogin = false
}
})
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
}
function refreshToken() {
const refreshTokenValue = getRefreshToken()
return new Promise<any>((resolve, reject) => {
uni.request({
method: 'POST',
timeout,
url: getBaseUrl() + '/admin-api/system/auth/refresh-token?refreshToken=' + encodeURIComponent(refreshTokenValue),
header: {
tenantId: '1'
},
dataType: 'json'
}).then(response => {
const data = (response as any).data
const code = data.code || 200
if (code === 200 || code === 0) {
resolve(data.data)
return
}
reject(data)
})
.catch(error => {
reject(error)
})
})
}
function retryRequestList() {
requestList.forEach(item => {
sendRequest(item.config).then(item.resolve).catch(item.reject)
})
requestList = []
}
function rejectRequestList(error: any) {
requestList.forEach(item => {
item.reject(error)
})
requestList = []
}
async function handleRefreshToken<T>(config: RequestConfig): Promise<ResponseData<T>> {
if (!getRefreshToken()) {
return handleAuthorized()
}
if (!isRefreshToken) {
isRefreshToken = true
try {
const tokenData = await refreshToken()
setToken(tokenData)
isRefreshToken = false
retryRequestList()
return sendRequest<T>(config)
} catch (error) {
rejectRequestList(error)
return handleAuthorized()
} finally {
isRefreshToken = false
}
}
return new Promise((resolve, reject) => {
requestList.push({
config,
resolve: resolve as (value: ResponseData<any>) => void,
reject
})
})
}
async function sendRequest<T>(config: RequestConfig): Promise<ResponseData<T>> {
const requestConfig = prepareConfig(config)
let response: any
try {
response = await uni.request({
method: (requestConfig.method || 'GET').toUpperCase() as any,
timeout: requestConfig.timeout || timeout,
url: (requestConfig.baseUrl || getBaseUrl()) + requestConfig.url,
data: requestConfig.data,
header: requestConfig.header,
dataType: 'json'
})
} catch (error) {
handleRequestError(error)
throw error
}
const data: ResponseData<T> = response.data as ResponseData<T>
const code = data.code || 200
// @ts-ignore
const msg: string = errorCode[code] || data.msg || errorCode['default']
if (code === 401) {
return handleRefreshToken<T>(config)
} else if (code === 500) {
toast(msg)
throw data
} else if (code !== 200 && code !== 0) {
toast(msg)
throw code
}
return data
}
const request = <T>(config: RequestConfig): Promise<ResponseData<T>> => {
const shouldShowLoading = config.showLoading !== false
if (shouldShowLoading) {
modal.loading(config.loadingText || '加载中...')
}
return sendRequest<T>(config)
.finally(() => {
if (shouldShowLoading) {
modal.closeLoading()
}
})
}
export function postAction(url: string, data?: any, isToken: boolean = true) {
return request({ data, url, method: 'POST', headers: { isToken }, })
}
export function getAction(url: string, params?: any, isToken: boolean = true) {
return request({ params, url, method: 'GET', headers: { isToken }, })
}
export function putAction(url: string, data?: any, isToken: boolean = true) {
return request({ data, url, method: 'PUT', headers: { isToken }, })
}
export function deleteAction(url: string, data?: any, isToken: boolean = true) {
return request({ data, url, method: 'DELETE', headers: { isToken }, })
}
export default request