import useUserStore from '../store/user' import { getrefreshtoken } from '@/apis/longin' import { getToken, setToken, removeToken } from '@/utils/auth' import { goToPage, checkConfigFileExists, readConfigFile, createDefaultConfig } from '@/utils/util' interface Response { code: number data: object msg: string } // let appVersion = '' // plus.runtime.getProperty(plus.runtime.appid, (info) => { // appVersion = info.version // }) // let newhttp = '' //请求ip // let newpro = '' //请求端口 let newhttp = import.meta.env.VITE_APP_BASE_URL let newpro = import.meta.env.VITE_APP_BASE_URLpro let newapi = import.meta.env.VITE_APP_BASE_PRE //请求的api开头 let htpurl = '' //正式的加htp的 // #ifdef APP-PLUS const configFileName = 'app_config.json' //const configFilePath = `${plus.io.PRIVATE_DOC}/${configFileName}`; // 私有目录 // 或 const configFilePath = `${plus.io.PUBLIC_DOWNLOADS}/${configFileName}` // 公共目录 async function handleConfigFile() { try { const exists = await checkConfigFileExists(configFilePath, configFileName) if (exists) { const config = await readConfigFile(configFilePath, configFileName) console.log('读取配置:', config) newhttp = config.url newpro = config.pro const userStore = useUserStore() userStore.seturlip(newhttp) userStore.seturlpro(newpro) userStore.setallurl(newhttp + ':' + newpro + newapi) return config } else { newhttp = import.meta.env.VITE_APP_BASE_URL newpro = import.meta.env.VITE_APP_BASE_URLpro const userStore = useUserStore() userStore.seturlip(newhttp) userStore.seturlpro(newpro) userStore.setallurl(newhttp + ':' + newpro + newapi) const defaultConfig = await createDefaultConfig(configFilePath, configFileName, { url: newhttp, pro: newpro, Version: 'appVersion' }) console.log('生成默认配置:', defaultConfig) return defaultConfig } } catch (err) { newhttp = import.meta.env.VITE_APP_BASE_URL newpro = import.meta.env.VITE_APP_BASE_URLpro console.error('操作失败:', err) throw err } } // 调用示例 // handleConfigFile().then((config) => { // // 使用配置数据 // //debugger // }) // #endif const requestObj = { isLock: false, methodstr: 'POST', http({ url = '', data = {}, isPost = '0', isSinglePost = false, isToken = true, timeout = 20000 }) { const _this = this const userStore = useUserStore() return new Promise(function (resolve, reject) { if (isSinglePost && _this.isLock) { reject({ message: '加载中' }) } // debugger _this.isLock = true //debugger // console.log('lsdfcs', userStore) const header = { 'content-type': 'application/json', // 'content-type': 'application/x-www-form-urlencoded', // Authorization: '' Bearerauth: '' } // if (isPost == '3') { // header['content-type'] = 'application/x-www-form-urlencoded' // } if (getToken() && isToken) { // header['Authorization'] = 'Bearer ' + userStore.token header['Bearerauth'] = 'Bearer ' + getToken() } let htconfig = { url: url, data: data, isPost: isPost, isSinglePost: isSinglePost, isToken: isToken, timeout: timeout, header: header } // #ifdef H5 // debugger url = import.meta.env.VITE_APP_BASE_PRE + url // #endif // debugger // #ifndef H5 // url = import.meta.env.VITE_APP_BASE_URL + ':' + import.meta.env.VITE_APP_BASE_URLpro + import.meta.env.VITE_APP_BASE_PRE + url // url = import.meta.env.VITE_APP_BASE_URL + ':' + import.meta.env.VITE_APP_BASE_URLpro + newapi + url // if (!userStore.allurl) { // newhttp = import.meta.env.VITE_APP_BASE_URL // newpro = import.meta.env.VITE_APP_BASE_URLpro // userStore.seturlip(newhttp) // userStore.seturlpro(newpro) // userStore.setallurl(newhttp + ':' + newpro + newapi) // } userStore.seturlip(newhttp) userStore.seturlpro(newpro) userStore.setallurl(newhttp + ':' + newpro + newapi) url = userStore.allurl + url console.log('11111', url) // #endif // debugger switch (isPost) { case '0': _this.methodstr = 'POST' break case '1': _this.methodstr = 'GET' break case '2': _this.methodstr = 'put' break default: _this.methodstr = 'DELETE' // 当 expression 不匹配任何 case 时执行的代码 } // uni.showLoading({ // title: '加载中...', // duration: 15000 // 可根据实用场景设置时间 // }) uni.request({ url, header, data, // method: isPost ? 'POST' : 'GET', method: _this.methodstr, timeout: timeout, success(res) { // debugger // uni.hideLoading() // console.log('55dfdsfsd5', res.data) res.data.code = res.data.code == 'ok' ? 200 : res.data.code const data = res.data as Response if (res.statusCode === 200) { if (data.code == 200) { // 成功 resolve(res.data) } else if (data.code == 401) { // uni.reLaunch({ // url: '/pages/login/login' // }) } else if (data.code == 601) { // userStore.setrefreshtoken() // uni.showToast({ title: data.msg, icon: 'none' }) // setTimeout(() => { // goToPage({ // url: 'pages/login/login', // mode: 'navigateTo' // }) // }, 1000) return handleTokenRefresh(htconfig) .then((result) => resolve(result)) .catch((error) => reject(error)) } else { uni.showToast({ title: data.msg, icon: 'none' }) reject(res.data) } } else { uni.showToast({ title: '响应错误', icon: 'none' }) reject({ message: '响应错误' }) } }, fail(err) { // uni.hideLoading() console.log('fail', err) uni.showToast({ title: '网络错误', icon: 'none' }) reject({ message: '网络错误' }) }, complete() { // uni.hideLoading() _this.isLock = false } }) }) } } // 请求队列与刷新状态管理 let requestQueue: any = [] let isRefreshing = false let tokenRefreshPromise: any = null /** * 处理Token刷新和请求重试的核心函数 * @param {Object} config - 原始请求配置 * @returns {Promise} - 返回处理结果 */ const handleTokenRefresh = (config: any) => { const userStore = useUserStore() return new Promise((resolve, reject) => { // 将当前请求添加到队列 requestQueue.push({ resolve, reject, config }) // 如果已经在刷新token,则不再重复刷新 if (tokenRefreshPromise) { return } // 如果没有在刷新token,则开始刷新 if (!isRefreshing) { isRefreshing = true const rtoken = userStore.refreshtoken if (!rtoken) { // 没有刷新token,直接跳转登录 resetQueueAndRefreshState(new Error('未找到刷新token')) showLoginConfirm() reject(new Error('未找到刷新token')) return } // 创建token刷新Promise并保存引用 tokenRefreshPromise = getrefreshtoken(rtoken) .then((response: any) => { // const { data = {} } = response; // const { accessToken, refreshToken: newRefreshToken } = data; // debugger let accessToken = response.data if (!accessToken) { throw new Error('刷新token失败:未获取到新token') } // 更新存储的token // setToken(accessToken); // uni.setStorageSync(appConfig.cache_key.RefreshToken, newRefreshToken); setToken(accessToken) // userInfo.value.token = response // 处理队列中的所有请求 return processQueue(accessToken) }) .catch((error) => { console.log('token刷新失败', error) // 通知队列中所有请求失败 resetQueueAndRefreshState(error || new Error('无效的会话,或者会话已过期,请重新登录')) // 显示登录确认对话框 showLoginConfirm() throw error // 继续传递错误 }) .finally(() => { // 重置刷新状态和Promise引用 tokenRefreshPromise = null isRefreshing = false }) } }) } /** * 处理队列中的所有请求 * @param {String} newToken - 新的访问令牌 * @returns {Promise} - 返回处理结果 */ const processQueue = async (newToken) => { const currentQueue = [...requestQueue] // 复制当前队列,防止处理过程中队列变化 requestQueue = [] // 清空队列 try { // 确保token已完全保存后再处理请求 await new Promise((resolve) => setTimeout(resolve, 50)) // 依次处理队列中的请求 const results = await Promise.allSettled( currentQueue.map(async ({ resolve, reject, config }) => { console.log('222222222222', config) try { // 更新请求头中的token config.header['Bearerauth'] = 'Bearer ' + newToken // 重新发起请求 const result = await requestObj.http({ ...config, retryCount: (config.retryCount || 0) + 1 }) // 使用setTimeout确保异步操作完成 setTimeout(() => resolve(result), 0) return result } catch (error) { console.error('重试请求失败:', error) reject(error) throw error } }) ) return results } catch (error) { console.error('队列处理失败:', error) throw error } finally { isRefreshing = false } } /** * 重置队列和刷新状态 * @param {Error} error - 错误信息 */ const resetQueueAndRefreshState = (error: any) => { // 通知队列中所有请求失败 requestQueue.forEach(({ reject }) => { reject(error) }) // 重置队列和刷新状态 requestQueue = [] isRefreshing = false tokenRefreshPromise = null } /** * 显示登录确认对话框 */ const showLoginConfirm = () => { // this.$modal.confirm('确定要退出系统吗?').then(() => { // this.userStore.userlogOut(); // }); // showConfirmh('未登录或登录状态过期,您可以继续留在该页面,或者重新登录?').then((res: any) => { // if (res.confirm) { // uni.navigateTo({ // url: '/pages/login' // }) // } // }) uni.showModal({ title: '系统提示', content: '登录状态过期,您可以继续留在该页面,或者重新登录?', cancelText: '取消', confirmText: '确定', success: function (res) { if (res.confirm) { uni.reLaunch({ url: '/pages/login/login' }) } } }) } export const request = requestObj