import { apiUrl } from '@/config/global-config.js'
import { useUserStore } from '../stores'
import { usePageRoute } from "@/composable/usePageRoute.js"
const DEFAULT_CONFIG = {timeout: 60000,
}
const refreshToken = async () => {const userStore = useUserStore()try {const response = await uni.request({url: apiUrl + '/auth/refresh', method: 'POST',header: {'Content-Type': 'application/json','Authorization': `Bearer ${userStore.token}`}})if (response.data.code === 200) {userStore.setToken(response.data.data.token)return true}return false} catch (error) {return false}
}
let isRefreshing = false
let refreshSubscribers = []
const onRefreshed = (token) => {refreshSubscribers.forEach(callback => callback(token))refreshSubscribers = []
}
const addSubscriber = (callback) => {refreshSubscribers.push(callback)
}
const requestInterceptor = (config) => {const userStore = useUserStore()const token = userStore.tokenconst isMapApi = /apis\.map\.qq\.com/.test(config.url)if (token && !isMapApi) {config.header.Authorization = `Bearer ${token}`}return config
}
const responseInterceptor = async (response) => {const userStore = useUserStore()const code = response.data.codeconst msg = response.data.msgconst data = response.dataswitch (code) {case 200:return datacase 401: {if (config.url.includes('/auth/refresh')) {await handleLogout()return Promise.reject(new Error('登录已失效'))}if (!isRefreshing) {isRefreshing = truetry {const refreshResult = await refreshToken()if (refreshResult) {const newToken = userStore.tokenonRefreshed(newToken)config.header.Authorization = `Bearer ${newToken}`return request(config)} else {await handleLogout()return Promise.reject(new Error('登录已失效'))}} finally {isRefreshing = false}}return new Promise((resolve) => {addSubscriber((token) => {config.header.Authorization = `Bearer ${token}`resolve(request(config))})})}default:uni.showToast({icon: 'none',title: msg || '请求错误',duration: 2000})return Promise.reject(new Error(msg || '请求错误'))}
}
const handleLogout = async () => {const userStore = useUserStore()const pageRoute = usePageRoute()const fullPagePath = pageRoute.getCurrentFullPagePath()uni.setStorageSync('fullPage', fullPagePath)uni.$msgBox('登录已失效,请重新登录', 2000)userStore.clearToken()userStore.clearUser()await uni.$delay(2000)uni.reLaunch({ url: '/pages/login/login' })
}
const request = (options = {}) => {const config = {...DEFAULT_CONFIG,...options,header: {'Content-Type': 'application/json',...options.header}}config.url = apiUrl + config.urlconst interceptedConfig = requestInterceptor(config)return new Promise((resolve, reject) => {uni.request({...interceptedConfig,success: async (res) => {try {const result = await responseInterceptor(res)resolve(result)} catch (error) {reject(error)}},fail: (error) => {uni.showToast({icon: 'none',title: '网络错误,请检查网络连接',duration: 2000})reject(error)},complete: () => {}})})
}
export const $get = (url, data, options = {}) => {return request({url,data,method: 'GET',...options})
}export const $post = (url, data, options = {}) => {return request({url,data,method: 'POST',...options})
}
uni.$get = $get
uni.$post = $post