HttpClient.ts 5.82 KB
import axios, { AxiosRequestConfig } from 'axios'
import { uniAdapter } from 'fant-axios-adapter'
import AxiosCancelToken from './AxiosCancelToken'
const axiosCancelToken = new AxiosCancelToken()
axios.defaults.timeout = 30000
import { storeToRefs } from 'pinia'
export default class ApiClient {
	/**
	 * 创建axios
	 * @param abortRequest 取消请求配置,可选值:same(取消相同请求)、all(取消所有请求)、none(不取消请求)
	 * @returns
	 */
	public static server(abortRequest : 'same' | 'all' | 'none' = 'none') {
		// 可以在这里拦截
		const baseURL = ApiClient.getBaseURL()
		return ApiClient.create(baseURL, abortRequest)
	}
	public static getBaseURL() {
		return 'http://39.99.131.18:9266/mini/'
	}

	private static create(baseURL : string, abortRequest : 'same' | 'all' | 'none' = 'none') {
		const instance = axios.create({
			withCredentials: true,
			baseURL: baseURL,
			adapter: uniAdapter // 指定适配器
		})
		const isRefreshing = false
		instance.interceptors.request.use(
			(request) => {
				// 设置conten-type
				// request.headers ? (request.headers['Content-Type'] = 'application/json') : (request.headers = { 'Content-Type': 'application/json' })
				// 设置请求唯一标识(便于查询请求日志)
				request.headers.trace_id = new Date().getTime()
				switch (abortRequest) {
					case 'all':
						axiosCancelToken.removeAllRequest()
						break
					case 'same':
						axiosCancelToken.removeRequest(request)
						break
					default:
						break
				}
				request.headers['Authorization'] = wx.getStorageSync('token') || ""
				axiosCancelToken.addRequest(request)

				if (isRefreshing && !request.url.includes('initAccount')) {
					// request._paused = true
					console.log('isRefreshing need abort url:', request.url)
					axiosCancelToken.removeRequest(request)
				}
				return request
			},
			(error) => {
				return Promise.reject(error)
			}
		)

		instance.interceptors.response.use(
			(response) => {
				// 此处为前后端约定的接口成功的字段,旨在处理状态码为200的错误响应,开发者可自行调整
				console.log('response',response)
				if (response.data.code === 200) {
					// console.log('请求response',response)
					return response.data
				} else if (response.data.code === 401) {
					// token失效
					uni.reLaunch({
						url: '/pages/login/index'
					})
					const error : Record<string, any> = {}
					if (response.data.code) {
						error.code = response.data.code
					}
					if (response.data.msg) {
						error.msg = response.data.msg
					} else {
						error.msg = response.status + '服务器内部异常'
					}
					console.log('error', error)
					return Promise.reject(error)
				} else if (response.data.code === 603) {
					// 用户已禁用
					// authStore.logout()
					uni.showModal({
						title: '提示',
						content: response.data.msg || '您的账户已禁用',
						showCancel: false, // 只显示确认按钮
						confirmText: '我知道了',
						success: (res) => {
							if (res.confirm) {
								// 用户点击了确认按钮,退出小程序
								wx.exitMiniProgram({
									complete: (e) => {
										console.log(e)
									}
								})
							}
						},
					});
					return Promise.reject()
				} else if (response.data.code === 500 && response.data.msg === "无手机号") {

					axiosCancelToken.removeAllRequest();
					uni.redirectTo({
						url: '/pages/login/Login'
					})
					return Promise.reject(response.data)

				} else {
					const error : Record<string, any> = {}
					if (response.data.code) {
						error.code = response.data.code
					}
					if (response.data.msg) {
						error.msg = response.data.msg
					} else {
						error.msg = response.status + '服务器内部异常'
					}
					// error.response = response.data
					console.log('error', error)
					return Promise.reject(error)
				}
			},
			(error) => {
				if (error.code === 'ERR_CANCELED') {
					return Promise.reject()
				}
				if (error.status !== 0 && !error.status) {
					console.error(error)
					const newError = error as any
					newError.msg = newError.errMsg || '请检查网络设置'
					return Promise.reject(newError)
				}
				const pages = getCurrentPages() as any[]
				switch (error.status) {
					// 小程序切换页面会导致正在处理中的请求返回状态码为0 这里还没有什么比较好的处理方案
					// case 0:
					//   error.msg = '请检查网络设置'
					//   break
					case 1:
						error.msg = '网络超时!'
						break
					case 401:
						setTimeout(() => {
							uni.showToast({ title: '登录已过期,请重新登录!', icon: 'none' })
						}, 300)
						break

					case 403:
						error.msg = `${error.status} 禁止访问!`
						break
					case 500:
						error.msg = `${error.status} 服务内部异常!`
						break
					case 502:
						error.msg = `${error.status} 服务器暂不可用!`
						break
					case 503:
						error.msg = `${error.status} 服务器升级中!`
						break
					case 404:
						error.msg = `${error.status} 服务器无回应!`
						break
					case 603:
						// authStore.logout()
						axiosCancelToken.removeAllRequest();
						uni.showModal({
							title: '提示',
							content: error.msg || '您的账户已禁用',
							showCancel: false, // 只显示确认按钮
							confirmText: '我知道了',
							success: (res) => {
								if (res.confirm) {
									// 用户点击了确认按钮,退出小程序
									wx.exitMiniProgram({
										complete: (e) => {
											console.log(e)
										}
									})
								}
							},
						});
						break
					default:
						error.msg = `${error.status} ${error.data.msg || '未知错误!'}`
				}
				return Promise.reject(error)
			}
		)
		return instance
	}
	public get<T = any>(url : string, params ?: any) : Promise<Result<T>> {
		return instance.request<T>({
			method: 'get',
			url,
			params,
		});
	}
}