/** * 封装的axios的工具类 * 负责请求的公共配置,以及请求拦截,响应拦截,错误处理,网络不佳处理 */ import axios from 'axios' import { Toast } from 'vant'; import errorCode from '@/utils/errorCode' import { getQyCode, authLock } from '@/utils/wecomLogin.ts'; axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' const service = axios.create({ baseURL: process.env.VUE_APP_AIDESIGN_API + '/standard', timeout: 180000, // withCredentials: true }); // request拦截器 service.interceptors.request.use(config => { const guidInfo = JSON.parse(window.localStorage.getItem('guidInfo')); const token = window.localStorage.getItem('AIToken'); if (guidInfo && guidInfo.guid) { let loginMark = guidInfo.guid; config.headers['loginmark'] = loginMark; } if (token) { config.headers['token'] = token; } if (config.data instanceof FormData) { // 若未手动设置 Content-Type,则删除默认值(让浏览器自动添加正确的 multipart 头) if (!config.headers['Content-Type']) { delete config.headers['Content-Type']; } } return config }, error => { Promise.reject(error) }) // 响应拦截器 service.interceptors.response.use(async(res) => { const code = res.data.StatusCode || 200; const msg = errorCode[code] || res.data.msg || errorCode['default'] if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { return res.data } if (code === 401) { console.log(msg) } else if (code === 500) { Toast(msg); return Promise.reject(new Error(msg)) } else if (code === 420) { // 双重判断:内存锁 + 本地缓存锁 const isLock = authLock.isAuthorizing || window.localStorage.getItem('isWechatAuthorizing') === 'true'; if (isLock) { return Promise.reject(new Error('正在授权,请勿重复操作')); } // 1. 立即加锁(关键:先锁再执行跳转) authLock.lock(); try { // 2. 取消所有未完成的请求(中断并发接口) const cancelTokenSource = axios.CancelToken.source(); service.defaults.cancelToken = cancelTokenSource.token; cancelTokenSource.cancel('授权失效,中断请求'); // 3. 微任务延迟跳转:给其他接口足够时间感知锁状态 await Promise.resolve(); // 或 setTimeout(() => {}, 0) // 4. 拼接授权链接并跳转(记录当前页面用于回跳) getQyCode() } catch (err) { // 异常时解锁 authLock.unlock(); console.error('授权跳转失败:', err); } } // else if (code !== 200 && code !== 204) { // Toast(msg); // return Promise.reject('error') // } else { return res.data } }, error => { console.log('完整错误信息:', error); console.log('错误配置:', error.config); // 1. 获取设备及企业微信信息 const userAgent = navigator.userAgent; // 核心信息 // console.log("userAgent=", userAgent) // 解析userAgent中的关键信息(可选,方便阅读) const isiOS = /iPhone|iPad|iPod/i.test(userAgent); const isAndroid = /Android/i.test(userAgent); const wxworkVersion = (userAgent.match(/wxwork\/(\d+\.\d+\.\d+)/) || [])[1]; // 企业微信版本号 const systemVersion = isiOS ? (userAgent.match(/OS (\d+_\d+)/) || [])[1].replace(/_/g, '.') : (userAgent.match(/Android (\d+\.\d+)/) || [])[1]; // Android版本(如13.0) // iOS版本(如16.5) // 2. 打印/记录设备信息 console.log('设备信息:', { userAgent: userAgent, // 原始字符串(用于完整分析) system: isiOS ? 'iOS' : isAndroid ? 'Android' : '未知', systemVersion: systemVersion || '未知',//系统版本 wxworkVersion: wxworkVersion || '未知', // 企业微信版本 networkType: (navigator.connection && navigator.connection.effectiveType) || (navigator.connection && navigator.connection.type) || '未知', timestamp: new Date().toLocaleString() // 报错时间 }); // console.log('err' + error) let { message } = error; if (message == "Network Error") { message = "网络异常,请切换网络后重试"; console.log('触发网络错误的请求URL:', error.config.url); } else if (message.includes("timeout")) { message = "系统接口请求超时"; } else if (message.includes("Request failed with status code")) { message = "系统接口" + message.substr(message.length - 3) + "异常"; } Toast(message); return Promise.reject(error) } ) export default service