| | |
| | | '/api/updatePhone' |
| | | ] |
| | | |
| | | // ✅ 请求缓存和防抖管理 |
| | | const pendingRequests = new Map(); // 存储正在等待的请求 |
| | | const requestCache = new Map(); // 存储缓存的请求结果 |
| | | |
| | | const request = config => { |
| | | const isToken = (config.headers || {}).isToken === false |
| | | config.header = config.header || {} |
| | |
| | | config.url = url |
| | | } |
| | | |
| | | // ✅ 生成唯一请求标识,包含 URL、方法和参数 |
| | | const requestKey = `${config.url}_${config.method}_${JSON.stringify(config.data || {})}`; |
| | | |
| | | // ✅ 检查缓存 |
| | | if (requestCache.has(requestKey)) { |
| | | const cached = requestCache.get(requestKey); |
| | | if (cached.expiry > Date.now()) { |
| | | return Promise.resolve(cached.response); // 返回缓存结果 |
| | | } else { |
| | | requestCache.delete(requestKey); // 缓存过期,删除 |
| | | } |
| | | } |
| | | |
| | | // ✅ 防抖逻辑:如果短时间内有相同请求,取消之前的 |
| | | if (pendingRequests.has(requestKey)) { |
| | | clearTimeout(pendingRequests.get(requestKey).timer); // 清除之前的定时器 |
| | | } |
| | | |
| | | // ✅ 判断是否需要加密 |
| | | const isEncryptApi = encryptApiList.includes(config.url) |
| | | const isEncryptApi = encryptApiList.includes(config.url); |
| | | const isLoginRequest = config.url.includes('/login'); |
| | | |
| | | // 登录接口示例(假如你的登录接口是 /api/login) |
| | | const isLoginRequest = config.url.includes('/login') |
| | | |
| | | let data = config.data |
| | | let data = config.data; |
| | | if (isEncryptApi) { |
| | | console.log('[加密前的data]', config.data) |
| | | data = encrypt(JSON.stringify(config.data)) |
| | | console.log('[加密前的data]', config.data); |
| | | data = encrypt(JSON.stringify(config.data)); |
| | | } else if (isLoginRequest) { |
| | | data = JSON.stringify(config.data) |
| | | data = JSON.stringify(config.data); |
| | | } else { |
| | | // 其他接口保持原样 |
| | | data = config.data |
| | | data = config.data; |
| | | } |
| | | |
| | | return new Promise((resolve, reject) => { |
| | | uni.request({ |
| | | method: config.method || 'get', |
| | | timeout: config.timeout || timeout, |
| | | url: config.baseUrl || baseUrl + config.url, |
| | | data: data, |
| | | header: config.header, |
| | | responseType: config.responseType || 'text', |
| | | dataType: config.responseType === 'arraybuffer' ? undefined : 'json' |
| | | }).then(response => { |
| | | let [error, res] = response |
| | | if (error) { |
| | | toast('后端接口连接异常') |
| | | reject('后端接口连接异常') |
| | | return |
| | | } |
| | | // ✅ 设置防抖定时器 |
| | | const timer = setTimeout(() => { |
| | | pendingRequests.delete(requestKey); // 请求发送后移除 |
| | | |
| | | let resData |
| | | try { |
| | | if (isEncryptApi) { |
| | | const decrypted = decrypt(res.data) |
| | | resData = JSON.parse(decrypted) |
| | | } else if (isLoginRequest) { |
| | | resData = typeof res.data === 'string' ? JSON.parse(res.data) : res.data |
| | | } else { |
| | | resData = res.data |
| | | uni.request({ |
| | | method: config.method || 'get', |
| | | timeout: config.timeout || timeout, |
| | | url: config.baseUrl || baseUrl + config.url, |
| | | data: data, |
| | | header: config.header, |
| | | responseType: config.responseType || 'text', |
| | | dataType: config.responseType === 'arraybuffer' ? undefined : 'json' |
| | | }).then(response => { |
| | | let [error, res] = response; |
| | | if (error) { |
| | | toast('后端接口连接异常'); |
| | | reject('后端接口连接异常'); |
| | | return; |
| | | } |
| | | } catch (e) { |
| | | console.error('响应解析失败:', e) |
| | | toast('响应数据处理失败') |
| | | reject('响应数据处理失败') |
| | | return |
| | | } |
| | | |
| | | if (config.responseType === 'arraybuffer') { |
| | | resolve(resData) |
| | | return |
| | | } |
| | | |
| | | const code = resData.code || 200 |
| | | const msg = errorCode[code] || resData.msg || errorCode['default'] |
| | | |
| | | if (code === 401) { |
| | | showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => { |
| | | if (res.confirm) { |
| | | store.dispatch('LogOut').then(() => { |
| | | uni.reLaunch({ url: '/pages/login' }) |
| | | }) |
| | | let resData; |
| | | try { |
| | | if (isEncryptApi) { |
| | | const decrypted = decrypt(res.data); |
| | | resData = JSON.parse(decrypted); |
| | | } else if (isLoginRequest) { |
| | | resData = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; |
| | | } else { |
| | | resData = res.data; |
| | | } |
| | | }) |
| | | reject('无效的会话,或者会话已过期,请重新登录。') |
| | | } else if (code === 500) { |
| | | toast(msg) |
| | | reject(resData) |
| | | } else if (code !== 200) { |
| | | toast(msg) |
| | | reject(resData) |
| | | } else { |
| | | resolve(resData) |
| | | } |
| | | }).catch(error => { |
| | | let { message } = error |
| | | if (message === 'Network Error') { |
| | | message = '后端接口连接异常' |
| | | } else if (message.includes('timeout')) { |
| | | message = '系统接口请求超时' |
| | | } else if (message.includes('Request failed with status code')) { |
| | | message = '系统接口' + message.substr(message.length - 3) + '异常' |
| | | } |
| | | toast(message) |
| | | reject(error) |
| | | }) |
| | | }) |
| | | } catch (e) { |
| | | console.error('响应解析失败:', e); |
| | | toast('响应数据处理失败'); |
| | | reject('响应数据处理失败'); |
| | | return; |
| | | } |
| | | |
| | | if (config.responseType === 'arraybuffer') { |
| | | // ✅ 缓存 arraybuffer 类型响应 |
| | | requestCache.set(requestKey, { |
| | | response: resData, |
| | | expiry: Date.now() + 5000 // 缓存 5 秒 |
| | | }); |
| | | resolve(resData); |
| | | return; |
| | | } |
| | | |
| | | const code = resData.code || 200; |
| | | const msg = errorCode[code] || resData.msg || errorCode['default']; |
| | | |
| | | if (code === 401) { |
| | | showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => { |
| | | if (res.confirm) { |
| | | store.dispatch('LogOut').then(() => { |
| | | uni.reLaunch({ url: '/pages/login' }); |
| | | }); |
| | | } |
| | | }); |
| | | reject('无效的会话,或者会话已过期,请重新登录。'); |
| | | } else if (code === 500) { |
| | | toast(msg); |
| | | reject(resData); |
| | | } else if (code !== 200) { |
| | | toast(msg); |
| | | reject(resData); |
| | | } else { |
| | | // ✅ 缓存成功响应 |
| | | requestCache.set(requestKey, { |
| | | response: resData, |
| | | expiry: Date.now() + 5000 // 缓存 5 秒 |
| | | }); |
| | | resolve(resData); |
| | | } |
| | | }).catch(error => { |
| | | let { message } = error; |
| | | if (message === 'Network Error') { |
| | | message = '后端接口连接异常'; |
| | | } else if (message.includes('timeout')) { |
| | | message = '系统接口请求超时'; |
| | | } else if (message.includes('Request failed with status code')) { |
| | | message = '系统接口' + message.substr(message.length - 3) + '异常'; |
| | | } |
| | | toast(message); |
| | | reject(error); |
| | | }).finally(() => { |
| | | // ✅ 清理 pendingRequests |
| | | pendingRequests.delete(requestKey); |
| | | }); |
| | | }, 500); // ✅ 防抖时间 500ms |
| | | |
| | | pendingRequests.set(requestKey, { timer }); |
| | | }); |
| | | } |
| | | |
| | | export default request |
| | | export default request; |