class HTTP { constructor(baseUrl) { this.baseUrl = baseUrl; this.hangUp = []; this.intercept = false; this.logInAgain = null; this.requestTask = null; this._pendingRequests = new Map(); // 默认请求配置 this.defaultTimeout = 30000; // 30秒默认超时 this.maxRetries = 2; // 最多重试次数 this.updateList = (content, getList) => { content.copyContent = JSON.parse(JSON.stringify(content)); content.pageSize = (content.pageNumber - 1) * (content.pageSize || 20); content.pageNumber = 1; getList() } this.formatNumber = (num, decimalPlaces = 2) => { if (!num && num !== 0) return ''; let [integer, decimal] = String(num.toFixed(decimalPlaces)).split('.'); integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return decimal ? `${integer}.${decimal}` : integer; } this.getSpecifiedImage = (obj, getType = false) => { obj.url = this.getImageUrl(obj.url) try { let type = getType ? 'compressed' : 'thumbnail'; let imgObj = obj.subfiles.find(v => v.type == type); return this.getImageUrl(imgObj.url || obj.url); } catch (error) { return this.getImageUrl(obj.url); } } this.getImageUrl = (url) => { if (!url) return ''; if (!/^https?:\/\//.test(url)) { url = this.baseUrl + url } return url; } this.jsessionid = uni.getStorageSync('JSESSIONID') || ''; console.log("接口地址", this.baseUrl); } // 生成请求唯一标识(用于防重复) _generateRequestKey(url, data, method) { return `${method}:${url}:${JSON.stringify(data)}`; } // 检查是否有相同请求正在执行 _isRequestPending(key) { const pending = this._pendingRequests.get(key); if (pending && pending.task) { const isValid = pending.timestamp && (Date.now() - pending.timestamp < 5000); if (isValid) return true; this._pendingRequests.delete(key); } return false; } // 记录请求 _addPendingRequest(key, task) { this._pendingRequests.set(key, { task, timestamp: Date.now() }); // 5秒后自动清理 setTimeout(() => this._pendingRequests.delete(key), 5000); } // 移除请求记录 _removePendingRequest(key) { this._pendingRequests.delete(key); } request({ url = "", data = {}, method = "POST", header = { 'content-type': 'application/json', "accesstoken": data.accesstoken || uni.getStorageSync('userMsg')?.token || '', "Cookie": `JSESSIONID=${this.jsessionid}` }, suffix = '/yos/rest', timeout = this.defaultTimeout, retry = this.maxRetries }) { // 分页预检:如果pageNumber大于pageTotal,直接返回空 try { if (data.content && data.content.pageNumber && data.content.pageTotal) { if (data.content.pageNumber > data.content.pageTotal) { return Promise.resolve({ code: 0 }); } } } catch (error) { } // 生成请求key,检查是否重复 const requestKey = this._generateRequestKey(url, data, method); if (this._isRequestPending(requestKey)) { console.log('检测到重复请求,已忽略:', url); return Promise.resolve({ code: 0, message: 'duplicate_request' }); } return new Promise((resolve, reject) => { let fullUrl = suffix.startsWith('http') ? suffix : (suffix == '/yos/rest' ? this.baseUrl : "") + suffix + url; if (fullUrl.includes('/index/loginbyaccount')) { fullUrl = fullUrl.replace('http://61.164.207.46:8900', 'http://61.164.207.46:8300'); fullUrl = fullUrl.replace('https://meida.cnyunl.com:888', 'https://crm.meida.com:16691'); } // 记录当前请求 this._addPendingRequest(requestKey, true); this._requestWithRetry(fullUrl, resolve, reject, data, method, header, retry, requestKey, timeout); }) } // 带重试的请求 _requestWithRetry(url, resolve, reject, data, method, header, retriesLeft, requestKey, timeout) { const doRequest = () => { // 取消之前的请求(如果存在) if (this.requestTask) { this.requestTask.abort(); } this._request(url, (result) => { this._removePendingRequest(requestKey); resolve(result); }, (err) => { if (retriesLeft > 0) { console.log(`请求失败,剩余重试次数: ${retriesLeft}`); // 网络错误时重试 setTimeout(() => { this._requestWithRetry(url, resolve, reject, data, method, header, retriesLeft - 1, requestKey, timeout); }, 1000); } else { this._removePendingRequest(requestKey); reject(err); } }, data, method, header, null, timeout); }; doRequest(); } getRequest({ url, method = "GET", header = { "Cookie": `JSESSIONID=${this.jsessionid}` }, timeout = this.defaultTimeout }) { return new Promise((resolve, reject) => { this._request(url, resolve, reject, {}, method, header, null, timeout); }) } // 取消所有请求 cancelAllRequests() { if (this.requestTask) { this.requestTask.abort(); this.requestTask = null; } this._pendingRequests.clear(); } _request(url, resolve, reject, data, method, header, showLoading, timeout = this.defaultTimeout) { if (showLoading) uni.showLoading({ title: showLoading, mask: true }); this.requestTask = uni.request({ url, data: data, method: method, header: header, timeout: timeout, success: (res) => { this._handleSessionCookies(res); try { if (res.data.pageNumber) { res.data.firstPage = res.data.pageNumber === 1; if (data.content && data.content.copyContent) { res.data.pageNumber = data.content.copyContent.pageNumber; res.data.pageTotal = data.content.copyContent.pageTotal; data.content.pageSize = data.content.copyContent.pageSize; delete data.content.copyContent } } } catch (error) { } resolve(res.data); }, fail: (err) => { reject(err); }, complete: (res) => { this.requestTask = null; if (showLoading) uni.hideLoading(); if (res.errMsg && !res.errMsg.includes('request:ok') && !res.errMsg.includes('abort')) { uni.showToast({ title: '网络异常,请稍后再试', icon: "none" }); } // 会话过期处理 - 使用更安全的方式 if (res.data && ['登录凭证已过期,请重新登录!', '身份令牌无效,请重新登陆!', '登陆状态已过期,请重新登陆!'].includes(res.data.msg)) { if (this.sessionExpiredNotified) return; this.sessionExpiredNotified = true; this.jsessionid = ''; uni.removeStorageSync('JSESSIONID'); // 使用 setTimeout 避免在页面生命周期中直接操作 setTimeout(() => { const pages = getCurrentPages(); const currentPage = pages.length > 0 ? pages[pages.length - 1] : null; const currentRoute = currentPage ? currentPage.route : ''; if (currentRoute !== 'pages/login/login') { uni.showModal({ title: '提示', content: '您的登录状态已过期,请重新登录。', showCancel: false, success: () => { this.sessionExpiredNotified = false; uni.reLaunch({ url: '/pages/login/login', fail: () => uni.redirectTo({ url: '/pages/login/login' }) }); }, fail: () => { this.sessionExpiredNotified = false; } }); } else { this.sessionExpiredNotified = false; } }, 100); } } }); } _handleSessionCookies(res) { try { const cookies = res.cookies || []; const headers = res.header || {}; const setCookie = headers['Set-Cookie'] || headers['set-cookie']; if (setCookie) { const cookieArray = Array.isArray(setCookie) ? setCookie : [setCookie]; cookies.push(...cookieArray); } for (const cookie of cookies) { const match = cookie.match(/JSESSIONID=([^;]+)/i); if (match && match[1]) { const newSessionId = match[1]; if (newSessionId !== this.jsessionid) { this.jsessionid = newSessionId; uni.removeStorageSync('JSESSIONID'); uni.setStorageSync('JSESSIONID', newSessionId); } break; } } } catch (error) { console.error('处理会话Cookie时出错:', error); } } } export { HTTP };