iot-ui-vue/src/utils/request.ts

214 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import axios from 'axios'
import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable'
import { notification as Notification } from 'jetlinks-ui-components'
import router from '@/router'
import { LoginPath } from '@/router/menu'
import { cleanToken, getToken, LocalStore } from '@/utils/comm'
import type { AxiosInstance, AxiosResponse } from 'axios'
interface AxiosResponseRewrite<T = any[]> extends AxiosResponse<T, any> {
result: T
success: boolean
}
export const SUCCESS_CODE = 200 // 成功代码
export const request = axios.create({
withCredentials: false,
baseURL: BASE_API_PATH,
timeout: 1000 * 60 * 5
})
/**
* POST method request
* @param {String} url
* @param {Object} [data]
* @param {String} responseType 如果接口是需要导出文件流那么responseType = 'blob'
* @param {Object|String} [ext] 扩展参数如果是配置headersext对象内包含headers对象如下
* {
headers: {'Content-Type': 'text/plain;charset=UTF-8'},
}
* @returns {AxiosInstance}
*/
export const post = function <T>(url: string, data = {}, params = {}, ext = {}) {
ext = typeof ext === 'string' ? { responseType: ext } : ext
return request<any, AxiosResponseRewrite<T>>({
...ext,
params,
method: 'POST',
url,
data
})
}
/**
* put method request
* @param {String} url
* @param {Object} [data]
* @returns {AxiosInstance}
*/
export const put = function <T>(url: string, data = {}) {
return request<any, AxiosResponseRewrite<T>>({
method: 'PUT',
url,
data
})
}
/**
* patch method request
* @param {String} url
* @param {Object} [data]
* @returns {AxiosInstance}
*/
export const patch = function <T>(url: string, data = {}) {
return request<any, AxiosResponseRewrite<T>>({
method: 'PATCH',
url,
data
})
}
/**
* GET method request
* @param {String} url
* @param {Object} [params]
* @param {Object} [ext] 扩展参数
* @returns {AxiosInstance}
*/
export const get = function <T>(url: string, params = {}, ext?: any) {
return request<any, AxiosResponseRewrite<T>>({
method: 'GET',
url,
params,
...ext
})
}
/**
* DELETE method request
* @param {String} url
* @param {Object} [params]
* @param {Object} [ext] 扩展参数
* @returns {AxiosInstance}
*/
export const remove = function <T>(url: string, params = {}, ext?: any) {
return request<any, AxiosResponseRewrite<T>>({
method: 'DELETE',
url,
params,
...ext
})
}
/**
* 获取文件流
* @param {String} url
* @param {Object} [params]
* @return {*}
*/
export const getStream = function(url: string, params = {}) {
return get<any>(url, params, {
responseType: 'arraybuffer' // 设置请求数据类型返回blob可解析类型
})
}
export const postStream = function(url: string, data = {}, params = {}) {
return post<any>(url, data, params, {
responseType: 'arraybuffer' // 设置请求数据类型返回blob可解析类型
})
}
const showNotification = (message: string, description: string, key?: string, show: boolean = true) => {
if (show) {
Notification.error({
key,
message: '',
description
})
}
}
/**
* 异常拦截处理器
* @param {Object} error
* @returns {Promise<never>}
*/
const errorHandler = (error: any) => {
if (error.response) {
const data = error.response.data
const status = error.response.status
if (status === 403) {
showNotification('Forbidden', (data.message + '').substr(0, 90), '403')
} else if (status === 500) {
showNotification('Server Side Error', (data.message + '').substr(0, 90), '500')
} else if (status === 400) {
showNotification('Request Error', (data.message + '').substr(0, 90), '400')
} else if (status === 401) {
showNotification('Unauthorized', '用户未登录', '401')
setTimeout(() => {
cleanToken()
router.replace({
path: LoginPath
})
}, 0)
} else if (status === 404) {
showNotification(error?.code, error?.response?.data?.message, '404')
}
} else if (error.response === undefined) {
showNotification(error.message, (error.stack + '').substr(0, 90), undefined)
}
return Promise.reject(error)
}
// request interceptor
request.interceptors.request.use(config => {
// 如果 token 存在
// 让每个请求携带自定义 token 请根据实际情况自行修改
const token = getToken()
if (!token) {
setTimeout(() => {
cleanToken()
router.replace({
path: LoginPath
})
}, 0)
return config
}
config.headers![TOKEN_KEY] = token
return config
}, errorHandler)
/**
* response interceptor
*/
request.interceptors.response.use(response => {
if (response.data instanceof ArrayBuffer) {
return response
} else {
const { status, message } = response.data
// 增加业务接口处理成功判断方式只需要判断返回参数包含success为true
if (typeof response.data === 'object' && typeof response.data.success === 'undefined') {
response.data.success = status === SUCCESS_CODE
}
// 如果返回的的是文件流那么return值则为response
if (response.headers['content-type'] === 'application/octet-stream; charset=UTF-8' || response.headers['content-type'] === 'application/vnd.ms-excel;charset=UTF-8') {
return response.data
} else {
return response.data
}
}
}, errorHandler)
export default {
request,
post,
get,
patch,
put,
remove,
getStream,
postStream
}