/** @format */ // MyRequest.ts import { ElMessage } from 'element-plus' import { useFetch, useRequestHeaders, useRuntimeConfig } from '#app' import { ResultEnum } from '@/enums/httpEnum' import { useUserStore } from '@/stores/modules/user' type UrlType = | string | Request | Ref | (() => string | Request) export interface RequestOptions { method?: any params?: any headers?: any server?: boolean [key: string]: any } export function useMyRequest() { const request = async ( url: UrlType, params: any, opt: RequestOptions = {}, ) => { const headers = useRequestHeaders(['cookie']) const { apiBase: baseURL } = useRuntimeConfig().public let { method = (opt?.method || 'GET') as string } = opt method = method.toUpperCase() // 处理请求体 let requestBody: any if (method === 'POST') { // 如果参数是 FormData 类型(文件上传),直接使用,不要 JSON.stringify if (params instanceof FormData) { requestBody = params // 删除 Content-Type header,让浏览器自动设置正确的 boundary delete headers['Content-Type'] } else { requestBody = JSON.stringify(params) headers['Content-Type'] = 'application/json' } } // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { await useFetch(url as string, { default: () => [], baseURL, method, params: { ...params }, headers, server: opt.server || false, credentials: 'include', body: requestBody, onRequest: ({ request, options }) => { // console.log('onResponseError--------aaaa:', options) const userStore = useUserStore() const { token } = storeToRefs(userStore) if (token.value) { options.headers = { ...opt.headers, 'Authorization': token.value, 'X-Access-Token': token.value, } } }, onRequestError: ({ request, options, error }) => { ElMessage.closeAll() error && ElMessage({ message: 'Sorry, The Data Request Failed', type: 'error', plain: true, }) }, // 响应成功+异常处理 onResponse: ({ request, response, options }) => { // console.log('onResponseError--------1:', request, response, options, opt) const data = response._data const { code, result, message } = data const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS if (hasSuccess) return resolve(result) let msg = '' switch (code) { case ResultEnum.TIMEOUT: msg = 'Login timeout, please login again.' // 超时,自动推出 useUserStore().logout() break default: if (message) msg = message } msg && !opt.isForbiddenErrorPrompt && ElMessage({ message: msg, type: 'error', plain: true, }) return reject(response._data) }, // 服务错误响应处理 onResponseError: (error: any) => { const { response, code, message } = error || {} const msg: string = response?.data?.message ?? '' const err: string = error?.toString?.() ?? '' let errMessage = '' if (code === 'ECONNABORTED' && message.includes('timeout')) { errMessage = 'The interface request timed out. Please refresh the page and try again.' } if (err?.includes('Network Error')) { errMessage = 'The network is abnormal. Please check whether your network connection is normal.' } const status = error?.response?.status switch (status) { case 400: errMessage = `${msg}` break // 401: Not logged in case 401: errMessage = msg || '用户没有权限' // 被动登出,带redirect地址 useUserStore().logout() break case 403: errMessage = '用户得到授权,但是访问是被禁止的' break case 404: errMessage = '网络请求错误,未找到该资源' break case 405: errMessage = '网络请求错误,请求方法未允许' break case 408: errMessage = '网络请求超时' break case 500: errMessage = '服务器错误,请联系管理员' break case 501: errMessage = '网络未实现' break case 502: errMessage = '网络错误' break case 503: errMessage = '服务器不可用,服务器暂时过载或维护' break case 504: errMessage = '网络超时' break case 505: errMessage = 'http版本不支持该请求' break default: } if (errMessage) { ElMessage({ message: errMessage, type: 'error', plain: true, }) } return reject(error) }, }) }) } return { get: (url: UrlType, params?: any, option?: RequestOptions) => { return request(url, params, { method: 'GET', ...option }) }, post: (url: UrlType, params?: any, option?: RequestOptions) => { return request(url, params, { method: 'POST', ...option }) }, put: (url: UrlType, params?: any, option?: RequestOptions) => { return request(url, params, { method: 'GET', ...option }) }, delete: (url: UrlType, params?: any, option?: RequestOptions) => { return request(url, params, { method: 'POST', ...option }) }, } }