import define from './define' import { useLocale } from '@/locale/useLocale'; const { getBackLocale } = useLocale(); let host = define.baseURL const defaultOpt = { load: true } // ------------- token刷新核心配置 ------------- const whiteList = ['/login', '/system/auth/refresh-token'] let requestQueue = [] let isRefreshingToken = false const isRelogin = { show: false } // ------------- 核心request方法 ------------- function request(config) { config.options = Object.assign(defaultOpt, config.options) const token = uni.getStorageSync('token') || '' const refreshToken = uni.getStorageSync('refreshToken') || '' const tenantId = '1' || uni.getStorageSync('tenantId') const systemCode = uni.getStorageSync('systemCode') || '' const locale = getBackLocale() // 构建请求头 let header = { "accept": 'application/json, text/plain, */*', "App-Code": systemCode, "Content-Type": "application/json;charset=UTF-8", "Jnpf-Origin": "app", "Vue-Version": "3", "Accept-Language": locale, "tenant-id": tenantId, ...config.header } header['App-Code'] = encodeURIComponent(header['App-Code']) if (token) header['Authorization'] = token // let url = config.url.indexOf('http') > -1 ? config.url : host + config.url let url = host + config.url console.log(url,'url---') // 显示加载中 if (config.options.load) { uni.showLoading({ title: config.options.loadText || '正在加载' }) } // 返回Promise,核心改造逻辑 return new Promise((resolve, reject) => { // 封装核心请求逻辑 const coreRequest = () => { uni.request({ url: url, data: config.data || {}, method: config.method || 'GET', header: header, timeout: define.timeout, success: async (res) => { uni.hideLoading(); if (res.statusCode === 200) { if (res.data.code == 200 || res.data.code == 0) { resolve(res.data) } else if ([401, 600, 601, 602].includes(res.data.code)) { // 白名单接口不处理 const isWhiteList = whiteList.some(v => config.url.includes(v)) if (isWhiteList) { // 仅提示错误,不触发登出 ajaxError(res.data, false) reject(res.data.msg) return } // ------------- 刷新token逻辑 ------------- if (!refreshToken) { // 无刷新token,触发登出 await handleAuthorized() reject(res.data.msg) return } if (isRefreshingToken) { requestQueue.push(() => coreRequest()) return } isRefreshingToken = true try { // 拼接URL参数 const refreshUrl = `${host}/admin-api/system/auth/refresh-token?refreshToken=${encodeURIComponent(refreshToken)}` // 调用刷新token接口 const refreshRes = await uni.request({ url: refreshUrl, method: 'POST', header: { 'tenant-id': tenantId, 'Content-Type': 'application/json' }, data: {} }) // 刷新成功处理 if (refreshRes.data && (refreshRes.data.code == 0 || refreshRes.data.code == 200)) { const newTokenData = refreshRes.data.data // 存储新token uni.setStorageSync('token', newTokenData.accessToken) uni.setStorageSync('refreshToken', newTokenData.refreshToken) // 更新请求头 header['Authorization'] = newTokenData.accessToken // 重试当前请求 coreRequest() // 执行队列请求 requestQueue.forEach(cb => cb()) requestQueue = [] } else { // 刷新token失败,触发登出 await handleAuthorized() reject('刷新token失败:' + (refreshRes.data?.msg || '接口返回异常')) } } catch (err) { // 刷新token异常,触发登出 await handleAuthorized() reject('刷新token异常:' + err.errMsg) } finally { isRefreshingToken = false requestQueue = [] } } else { // 普通业务错误,仅提示,不登出 ajaxError(res.data, false) reject(res.data.msg) } } else { // HTTP状态码错误,仅提示,不登出 ajaxError(res.data, false) reject(res.errMsg) } }, fail: (err) => { uni.hideLoading(); // 网络错误,仅提示,不登出 uni.showToast({ title: '连接服务器失败', icon: 'none' }) reject(err) } }) } coreRequest() }) } // ------------- 辅助函数 ------------- /** * 错误提示函数 * @param {Object} data 错误数据 * @param {Boolean} isAuthError 是否是认证错误(是否需要触发登出) */ function ajaxError(data, isAuthError = false) { uni.showToast({ title: data.msg || '请求出错,请重试', icon: 'none', duration: 2000, // 延长提示时间,提升体验 complete() { // 只有明确的认证错误且不在刷新token过程中,才触发登出 if (isAuthError && [600, 601, 602, 401].includes(data.code) && !isRefreshingToken) { setTimeout(() => handleAuthorized(), 1500) } } }) } /** * 处理登录过期逻辑(仅token失效时调用) */ async function handleAuthorized() { // 防止重复弹出登录弹窗 if (!isRelogin.show) { isRelogin.show = true try { const res = await uni.showModal({ title: '登录过期', content: '您的登录已过期,请重新登录', showCancelButton: false, confirmText: '重新登录' }) if (res.confirm) { // 清除登录相关缓存 uni.removeStorageSync('token') uni.removeStorageSync('refreshToken') uni.removeStorageSync('cid') uni.removeStorageSync('userInfo') uni.removeStorageSync('permissionList') uni.removeStorageSync('sysVersion') uni.removeStorageSync('dynamicModelExtra') // 跳转到登录页 uni.reLaunch({ url: '/pages/login/index' }) } } catch (err) { console.error('处理登录过期异常:', err) } finally { isRefreshingToken = false isRelogin.show = false } } } export default request