| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- 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 };
|