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 } // 全局网络状态标记(防止多请求覆盖) let GLOBAL_IS_NETWORK_ERROR = false; // ========== 核心:全局拦截登录跳转 ========== // 拦截所有跳登录页的操作,仅允许非断网场景跳转 function interceptLoginJump() { // 拦截 reLaunch(最常用的跳登录方式) const originalReLaunch = uni.reLaunch; uni.reLaunch = function(options) { // 如果是跳登录页 + 当前是网络错误 → 阻止跳转 if (options.url && options.url.includes('/pages/login/index') && GLOBAL_IS_NETWORK_ERROR) { console.log('【拦截】断网时禁止跳登录页'); uni.showToast({ title: '网络已断开,请先连接网络', icon: 'none', duration: 3000 }); return; // 终止跳转 } // 非登录页/非断网场景 → 正常跳转 originalReLaunch.call(uni, options); }; // 拦截其他跳转方式(兜底) const interceptors = ['navigateTo', 'redirectTo', 'switchTab']; interceptors.forEach(method => { const originalMethod = uni[method]; uni[method] = function(options) { if (options.url && options.url.includes('/pages/login/index') && GLOBAL_IS_NETWORK_ERROR) { return; } originalMethod.call(uni, options); }; }); } // 初始化拦截器(页面加载时执行一次) interceptLoginJump(); // ------------- 核心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(); GLOBAL_IS_NETWORK_ERROR = false; // 有响应 → 网络正常 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) { uni.showToast({ title: res.data.msg || '认证失败', icon: 'none' }); reject(res.data.msg); return; } // 无刷新token → 提示手动登录(不自动跳转) if (!refreshToken) { uni.showModal({ title: '登录过期', content: '您的登录已过期,请重新登录', showCancelButton: false, confirmText: '去登录' }).then(res => { if (res.confirm) { clearAuthStorage(); uni.reLaunch({ url: '/pages/login/index' }); // 这里会走拦截器,仅网络正常时跳转 } }); reject('登录过期,无刷新Token'); return; } if (isRefreshingToken) { requestQueue.push(() => coreRequest()); return; } isRefreshingToken = true; try { // 刷新token接口 const refreshUrl = `${host}/admin-api/system/auth/refresh-token?refreshToken=${encodeURIComponent(refreshToken)}`; 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; uni.setStorageSync('token', newTokenData.accessToken); uni.setStorageSync('refreshToken', newTokenData.refreshToken); header['Authorization'] = newTokenData.accessToken; coreRequest(); requestQueue.forEach(cb => cb()); requestQueue = []; } else { // 刷新失败 → 提示手动登录 uni.showModal({ title: '登录过期', content: '刷新登录状态失败,请重新登录', showCancelButton: false, confirmText: '去登录' }).then(res => { if (res.confirm) { clearAuthStorage(); uni.reLaunch({ url: '/pages/login/index' }); } }); reject('刷新Token失败:' + (refreshRes.data?.msg || '接口返回异常')); } } catch (err) { // 刷新token异常 → 判定为网络错误 GLOBAL_IS_NETWORK_ERROR = true; uni.showToast({ title: '网络异常,无法刷新登录状态', icon: 'none', duration: 3000 }); reject('网络异常:' + (err.errMsg || err.message)); } finally { isRefreshingToken = false; requestQueue = []; } } else { // 普通业务错误 uni.showToast({ title: res.data.msg || '请求出错,请重试', icon: 'none' }); reject(res.data.msg); } } else { // HTTP状态码错误 uni.showToast({ title: `请求失败[${res.statusCode}]`, icon: 'none' }); reject(res.errMsg); } }, fail: (err) => { uni.hideLoading(); GLOBAL_IS_NETWORK_ERROR = true; // 重置刷新状态,防止死锁 isRefreshingToken = false; requestQueue = []; // 仅提示网络错误,不跳转 uni.showToast({ title: '网络连接失败,请检查网络', icon: 'none', duration: 3000 }); reject({ isNetworkError: true, errMsg: err.errMsg }); } }) } coreRequest() }) } // ------------- 辅助函数 ------------- /** * 清除登录缓存 */ function clearAuthStorage() { uni.removeStorageSync('token'); uni.removeStorageSync('refreshToken'); uni.removeStorageSync('cid'); uni.removeStorageSync('userInfo'); uni.removeStorageSync('permissionList'); uni.removeStorageSync('sysVersion'); uni.removeStorageSync('dynamicModelExtra'); } export default request;