import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios' import axios from 'axios' import qs from 'qs' import type { Ref } from 'vue' import { ElNotification } from 'element-plus' import { ref } from 'vue' // 创建 axios 实例 let service: AxiosInstance export interface AxiosResponseData { code: number content: string } export function initService() { service = axios.create({ baseURL: '/api', timeout: 50000, headers: { 'Content-Type': 'application/json;charset=utf-8' }, paramsSerializer: (params) => { return qs.stringify(params) }, }) // 请求拦截器 service.interceptors.request.use( (config: InternalAxiosRequestConfig) => { return config }, (error: Error) => { return Promise.reject(error) }, ) // 响应拦截器 service.interceptors.response.use( (response: AxiosResponse) => { // 判断响应状态码是否为2xx if (response.status < 200 || response.status >= 300) { throw new Error(response.data?.content) } // 检查配置的响应类型是否为二进制类型('blob' 或 'arraybuffer'), 如果是,直接返回响应对象 if ( response.config.responseType === 'blob' || response.config.responseType === 'arraybuffer' ) { return response as unknown as AxiosResponse } return response.data as unknown as AxiosResponse }, (error: AxiosError) => { let message: string = '' if (error.response && error.response.status === 500) { message = '系统错误' } // if (error.config?.url === '/irs/data-do' && error.config?.method === 'get') { // return Promise.reject(new Error(message)) // } return Promise.reject(new Error(message)) }, ) } export interface UseAxiosOption { // 错误时不弹窗 hideErrorTip?: boolean } // 导出 axios 实例 export async function request, D = unknown>( config: AxiosRequestConfig, { hideErrorTip = false } = {} as UseAxiosOption, ): Promise { try { return await service(config) } catch (error) { if (!hideErrorTip) { ElNotification({ showClose: true, message: (error as Error)?.message, type: 'error', }) } return Promise.reject(error) } } export default request export interface UseRequestOption extends UseAxiosOption { defaultData?: R } export interface UseRequestResult { data: Ref error: Ref loading: Ref refresh: () => Promise } export function useRequest, D = unknown>( config: AxiosRequestConfig, { defaultData = {} as R, ...rest } = {} as UseRequestOption, ) { const data = ref(defaultData) as Ref const loading = ref(false) const error = ref() const fetchResource = async (conf = config): Promise => { loading.value = true try { data.value = await request(conf, rest) } catch (e) { error.value = e as Error } finally { loading.value = false } } const promise = new Promise((resolve) => { void fetchResource().finally(() => resolve({ data, error, loading, refresh: fetchResource })) }) as unknown as UseRequestResult & Promise> promise.data = data promise.error = error promise.loading = loading promise.refresh = fetchResource return promise }