| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- import type { uniappRequestAdapter } from '@alova/adapter-uniapp'
- import type { IResponse } from './types'
- import AdapterUniapp from '@alova/adapter-uniapp'
- import { createAlova } from 'alova'
- import { createServerTokenAuthentication } from 'alova/client'
- import VueHook from 'alova/vue'
- import { useTokenStore } from '@/store/token'
- import { toLoginPage } from '@/utils/toLoginPage'
- import { ContentTypeEnum, ResultEnum, ShowMessage } from './tools/enum'
- // 配置动态Tag
- export const API_DOMAINS = {
- DEFAULT: import.meta.env.VITE_SERVER_BASEURL,
- SECONDARY: import.meta.env.VITE_SERVER_BASEURL_SECONDARY,
- }
- // 添加全局标志,防止重复弹窗
- let loginModalShown = false
- /**
- * 创建请求实例
- */
- const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication<
- typeof VueHook,
- typeof uniappRequestAdapter
- >({
- // 如果下面拦截不到,请使用 refreshTokenOnSuccess by 群友@琛
- refreshTokenOnError: {
- isExpired: (error) => {
- console.log('error', error)
- return error.response?.status === ResultEnum.Unauthorized
- },
- handler: async () => {
- try {
- // await authLogin();
- console.log('拦截token失效')
- }
- catch (error) {
- // 切换到登录页
- // toLoginPage({ mode: 'reLaunch' })
- console.log('刷新token失败', error)
- throw error
- }
- },
- },
- })
- /**
- * alova 请求实例
- */
- const alovaInstance = createAlova({
- baseURL: API_DOMAINS.DEFAULT,
- ...AdapterUniapp(),
- // timeout: 7000,
- statesHook: VueHook,
- cacheFor: null,
- beforeRequest: (method) => {
- // 设置默认 Content-Type
- method.config.headers = {
- ContentType: method.type === 'POST' ? ContentTypeEnum.FORM_URLENCODED : ContentTypeEnum.JSON,
- // // #ifndef MP-WEIXIN
- // responseType: 'json',
- // // #endif
- Accept: 'application/json, text/plain, */*',
- ...method.config.headers,
- }
- console.log('method===>', method)
- const { config } = method
- const ignoreAuth = !config.meta?.ignoreAuth
- // 处理认证信息 自行处理认证问题
- if (ignoreAuth) {
- const tokenStore = useTokenStore()
- const token = tokenStore.validToken
- // const token = 'getToken()'
- if (!token) {
- throw new Error('[请求错误]:未登录')
- }
- method.config.headers['X-Access-Token'] = `${token}`
- method.config.headers.AppType = '7'
- // method.config.headers.token = token;
- }
- // 处理动态域名
- if (config.meta?.domain) {
- method.baseURL = config.meta.domain
- console.log('当前域名', method.baseURL)
- }
- },
- responded: {
- onSuccess: (response, method) => {
- const { config } = method
- const { requestType } = config
- const {
- statusCode,
- data: rawData,
- errMsg,
- } = response as UniNamespace.RequestSuccessCallbackResult
- // 处理特殊请求类型(上传/下载)
- if (requestType === 'upload' || requestType === 'download') {
- return response
- }
- // 特殊处理:返回原始响应
- if (config.meta?.returnResponse) {
- return response
- }
- // 处理 HTTP 状态码错误
- if (statusCode !== 200) {
- // 直接处理401错误,跳转到登录页面
- if (statusCode === 401) {
- if (!loginModalShown) {
- loginModalShown = true
- uni.showModal({
- title: '提示',
- content: '登录已过期,请重新登录',
- confirmText: '去登录',
- cancelText: '回首页',
- success: ({ confirm, cancel }) => {
- loginModalShown = false // 重置标志
- if (confirm) {
- toLoginPage({ mode: 'reLaunch' })
- }
- else if (cancel) {
- uni.reLaunch({ url: '/pages/home/home' })
- }
- },
- fail: () => {
- loginModalShown = false // 重置标志
- }
- })
- useTokenStore().cleanToken()
- }
- // setTimeout(() => {
- // toLoginPage({ mode: 'reLaunch' })
- // }, 1500)
- throw new Error('登录已过期')
- }
- const errorMessage = ShowMessage(statusCode) || `HTTP请求错误[${statusCode}]`
- console.error('errorMessage===>', errorMessage)
- uni.showToast({
- title: errorMessage,
- icon: 'error',
- })
- throw new Error(`${errorMessage}:${errMsg}`)
- }
- // 处理业务逻辑错误
- const { code, message, result: data } = rawData as IResponse
- // 0和200当做成功都很普遍,这里直接兼容两者,见 ResultEnum
- if (code !== ResultEnum.Success0 && code !== ResultEnum.Success200) {
- if (config.meta?.toast !== false) {
- uni.showToast({
- title: message,
- icon: 'none',
- })
- }
- throw new Error(`请求错误[${code}]:${message}`)
- }
- // 处理成功响应,返回业务数据
- return data
- },
- // 添加网络错误处理
- onError: (error, method) => {
- // 处理网络错误(断网、超时、DNS解析失败等)
- console.error('网络错误:', error)
- // 避免重复提示
- if (error.message?.includes('HTTP请求错误') || error.message?.includes('请求错误[')) {
- return
- }
- let errorMessage = '网络错误,请检查网络连接'
- if (error.message?.includes('timeout')) {
- errorMessage = '请求超时,请稍后重试'
- }
- uni.showToast({
- title: errorMessage,
- icon: 'error',
- })
- }
- },
- })
- export const http = alovaInstance
|