1.添加alph币种(矿池分配及转账规则页面、费率页面、挖矿教程页面、起付额度限制、最新报块跳转、支付id跳转) 完成
2.api文档页面修改8个接口请求方式为post 3.优化代码币种添加通用币种信息及挖矿教程页面跳转通用 4.m2pool断网重连 60秒内重连 处理中 5.收益计算器显示值修改 取消四舍五入 直接保留10位小数 添加千位符分隔显示 6.coinbus 添加seo相关配置及站点地图 处理中
This commit is contained in:
179
mining-pool/src/utils/echarts.js
Normal file
179
mining-pool/src/utils/echarts.js
Normal file
@@ -0,0 +1,179 @@
|
||||
import { color } from "echarts";
|
||||
|
||||
//折线图
|
||||
export const line = {
|
||||
legend: {
|
||||
right: 100,
|
||||
formatter: function (name) {
|
||||
return name;
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
textStyle: {
|
||||
align: "left",
|
||||
},
|
||||
animation: false,
|
||||
// formatter: function (params) {
|
||||
// var res = params[0].axisValueLabel;
|
||||
|
||||
// for (let i = 0; i <= params.length - 1; i++) {
|
||||
// res += `</br>${params[i].marker} <span style="font-weight: bold">${params[i].value[1]}</span> ${params[i].seriesName}`;
|
||||
// }
|
||||
// return res;
|
||||
// },
|
||||
axisPointer: {
|
||||
animation: false,
|
||||
snap: true,
|
||||
label: {
|
||||
precision: 2, //坐标轴保留的位数
|
||||
},
|
||||
type: "cross", //cross shadow
|
||||
crossStyle: {
|
||||
//十字轴横线
|
||||
// opacity: "0",
|
||||
width: 0.5,
|
||||
},
|
||||
lineStyle: {
|
||||
// opacity: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
// type: "time",
|
||||
boundaryGap: false,
|
||||
|
||||
axisTick: {
|
||||
//去除刻度
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
//去除轴线
|
||||
show: false,
|
||||
},
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
position: "left",
|
||||
type: "value",
|
||||
// min: `dataMin`,
|
||||
// max: `dataMax`,
|
||||
// axisLabel: {
|
||||
// formatter: function (value) {
|
||||
// let data
|
||||
// if (value > 10000000) {
|
||||
// data = `${(value / 10000000)} KW`
|
||||
// } else if (value > 1000000) {
|
||||
// data = `${(value / 1000000)} M`
|
||||
// } else if (value / 10000) {
|
||||
// data = `${(value / 10000)} W`
|
||||
// }
|
||||
// return data
|
||||
// }
|
||||
// }
|
||||
},
|
||||
{
|
||||
position: "right",
|
||||
// type: "log",
|
||||
splitNumber: "5",
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
position: "right",
|
||||
// type: "log",
|
||||
splitNumber: "5",
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
position: "right",
|
||||
// type: "log",
|
||||
splitNumber: "5",
|
||||
show: false,
|
||||
},
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: "inside",
|
||||
start: 10,
|
||||
end: 100,
|
||||
maxSpan: 100,
|
||||
minSpan: 2,
|
||||
animation: false,
|
||||
},
|
||||
{
|
||||
type: "inside",//slider
|
||||
start: 10,
|
||||
end: 100,
|
||||
// showDetail: false,
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: "line",
|
||||
type: "line",
|
||||
smooth: false, //线条是否圆滑
|
||||
symbol: "circle",
|
||||
symbolSize: 5,
|
||||
showSymbol: false,
|
||||
itemStyle: {
|
||||
color: "#5721E4",
|
||||
borderColor: "rgba(221,220,107,0.1)",
|
||||
borderWidth: 12,
|
||||
},
|
||||
lineStyle: {
|
||||
//线条样式
|
||||
color: "#5721E4",
|
||||
width: "2",
|
||||
},
|
||||
data: [150, 230, 224, 218, 135, 147, 260],
|
||||
},
|
||||
|
||||
|
||||
|
||||
],
|
||||
}
|
||||
//柱状图
|
||||
export const bar ={
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
show:true
|
||||
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Direct',
|
||||
type: 'bar',
|
||||
barWidth: '60%',
|
||||
data: [10, 52, 200, 334, 390, 330, 220],
|
||||
itemStyle:{
|
||||
borderRadius:[100,100,0,0],
|
||||
color:"#7645EE",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
6
mining-pool/src/utils/errorCode.js
Normal file
6
mining-pool/src/utils/errorCode.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'401': '认证失败,无法访问系统资源,请重新登录',
|
||||
'403': '当前操作没有权限',
|
||||
'404': '访问资源不存在',
|
||||
'default': '系统未知错误,请反馈给管理员'
|
||||
}
|
||||
14
mining-pool/src/utils/fun.js
Normal file
14
mining-pool/src/utils/fun.js
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
import JSEncrypt from "jsencrypt"; //引入模块
|
||||
|
||||
const publicKey = `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwHkUfT2GAupZAL5DMnwETSywuPLIKUAR3hjhKvOls2u0YtIHlcfjhqGBfg0NEPi6Ig2GmK5KnjcdIppfNfBpSiJBEtMwM2E7WJbXBsYU0B4wB86XGW9fFQi0e8pGYvVbKvwP9MQeLnUC4xf2L+6Nw3xQZ9GAsE6GUJ4tUOSKK/QIDAQAB`
|
||||
export const encryption = (str) => {
|
||||
//创建实例
|
||||
const jse = new JSEncrypt()
|
||||
//添加秘钥 秘钥放过来
|
||||
jse.setPublicKey(publicKey)
|
||||
//加密
|
||||
let data = jse.encrypt(str)
|
||||
return data
|
||||
|
||||
}
|
||||
68
mining-pool/src/utils/loadingManager.js
Normal file
68
mining-pool/src/utils/loadingManager.js
Normal file
@@ -0,0 +1,68 @@
|
||||
// 全局 loading 状态管理器
|
||||
class LoadingManager {
|
||||
constructor() {
|
||||
this.loadingStates = new Map(); // 存储所有 loading 状态
|
||||
this.setupListeners();
|
||||
}
|
||||
|
||||
setupListeners() {
|
||||
// 监听网络重试完成事件
|
||||
window.addEventListener('network-retry-complete', () => {
|
||||
this.resetAllLoadingStates();
|
||||
});
|
||||
}
|
||||
|
||||
// 设置 loading 状态
|
||||
setLoading(componentId, stateKey, value) {
|
||||
const key = `${componentId}:${stateKey}`;
|
||||
this.loadingStates.set(key, {
|
||||
value,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
}
|
||||
|
||||
// 获取 loading 状态
|
||||
getLoading(componentId, stateKey) {
|
||||
const key = `${componentId}:${stateKey}`;
|
||||
const state = this.loadingStates.get(key);
|
||||
return state ? state.value : false;
|
||||
}
|
||||
|
||||
// 重置所有 loading 状态
|
||||
resetAllLoadingStates() {
|
||||
// 清除所有处于加载状态的组件
|
||||
const componentsToUpdate = [];
|
||||
|
||||
this.loadingStates.forEach((state, key) => {
|
||||
if (state.value === true) {
|
||||
const [componentId, stateKey] = key.split(':');
|
||||
componentsToUpdate.push({ componentId, stateKey });
|
||||
this.loadingStates.set(key, { value: false, timestamp: Date.now() });
|
||||
}
|
||||
});
|
||||
|
||||
// 使用事件通知各组件更新
|
||||
window.dispatchEvent(new CustomEvent('reset-loading-states', {
|
||||
detail: { componentsToUpdate }
|
||||
}));
|
||||
}
|
||||
|
||||
// 重置特定组件的所有 loading 状态
|
||||
resetComponentLoadingStates(componentId) {
|
||||
const componentsToUpdate = [];
|
||||
|
||||
this.loadingStates.forEach((state, key) => {
|
||||
if (key.startsWith(`${componentId}:`) && state.value === true) {
|
||||
const stateKey = key.split(':')[1];
|
||||
componentsToUpdate.push({ componentId, stateKey });
|
||||
this.loadingStates.set(key, { value: false, timestamp: Date.now() });
|
||||
}
|
||||
});
|
||||
|
||||
return componentsToUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单例实例
|
||||
const loadingManager = new LoadingManager();
|
||||
export default loadingManager;
|
||||
48
mining-pool/src/utils/loadingStateMixin.js
Normal file
48
mining-pool/src/utils/loadingStateMixin.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import loadingManager from '../utils/loadingManager';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
componentId: this.$options.name || 'unnamed-component'
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 设置 loading 状态
|
||||
setLoading(stateKey, value) {
|
||||
// 同时更新组件本地状态和全局状态
|
||||
this[stateKey] = value;
|
||||
loadingManager.setLoading(this.componentId, stateKey, value);
|
||||
},
|
||||
|
||||
// 获取 loading 状态
|
||||
getLoading(stateKey) {
|
||||
return loadingManager.getLoading(this.componentId, stateKey);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// 监听重置 loading 状态事件
|
||||
this._resetHandler = (event) => {
|
||||
const { componentsToUpdate } = event.detail;
|
||||
componentsToUpdate.forEach(item => {
|
||||
if (item.componentId === this.componentId) {
|
||||
this[item.stateKey] = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener('reset-loading-states', this._resetHandler);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
// 清理监听器
|
||||
window.removeEventListener('reset-loading-states', this._resetHandler);
|
||||
|
||||
// 组件销毁时清理该组件的所有loading状态
|
||||
const componentsToUpdate = loadingManager.resetComponentLoadingStates(this.componentId);
|
||||
componentsToUpdate.forEach(item => {
|
||||
this[item.stateKey] = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
107
mining-pool/src/utils/publicMethods.js
Normal file
107
mining-pool/src/utils/publicMethods.js
Normal file
@@ -0,0 +1,107 @@
|
||||
//监听localstorage
|
||||
export const $addStorageEvent = function (type, key, data) {
|
||||
// localStorage
|
||||
if (type === 1) {
|
||||
// 创建一个StorageEvent事件
|
||||
var newStorageEvent = document.createEvent('StorageEvent');
|
||||
const storage = {
|
||||
setItem: function (k, val) {
|
||||
localStorage.setItem(k, val);
|
||||
// 初始化创建的事件
|
||||
newStorageEvent.initStorageEvent('setItem', false, false, k, null, val, null, null);
|
||||
// 派发对象
|
||||
window.dispatchEvent(newStorageEvent);
|
||||
}
|
||||
}
|
||||
return storage.setItem(key, data);
|
||||
} else {
|
||||
// sessionStorage
|
||||
// 创建一个StorageEvent事件
|
||||
var newStorageEvent = document.createEvent('StorageEvent');
|
||||
const storage = {
|
||||
setItem: function (k, val) {
|
||||
sessionStorage.setItem(k, val);
|
||||
// 初始化创建的事件
|
||||
newStorageEvent.initStorageEvent('setItem', false, false, k, null, val, null, null);
|
||||
// 派发对象
|
||||
window.dispatchEvent(newStorageEvent);
|
||||
}
|
||||
}
|
||||
return storage.setItem(key, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 防抖函数
|
||||
* @param {()=>void} fn 接收一个需要防抖的函数
|
||||
* @param {number} delay 延迟时间,单位 ms。默认为 0。 可选参数,表示重复执行的时间间隔,
|
||||
* @returns {()=>void} 返回一个实际执的函数
|
||||
*/
|
||||
|
||||
// 防抖函数
|
||||
export function Debounce(fn, delay) {
|
||||
let timer = null;
|
||||
return function () {
|
||||
let context = this;
|
||||
let args = arguments;
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
fn.apply(context, args);
|
||||
}, delay);
|
||||
};
|
||||
}
|
||||
|
||||
//节流函数
|
||||
// export function throttle(func, delay) {
|
||||
// let timer = null;
|
||||
// return function () {
|
||||
// if (!timer) {
|
||||
// func.apply(this, arguments);
|
||||
// timer = setTimeout(() => {
|
||||
// timer = null;
|
||||
// }, delay);
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
|
||||
// 节流函数
|
||||
export function throttle(fn, wait) {
|
||||
let inThrottle, lastFn, lastTime;
|
||||
return function() {
|
||||
const context = this,
|
||||
args = arguments;
|
||||
if (!inThrottle) {
|
||||
fn.apply(context, args);
|
||||
lastTime = Date.now();
|
||||
inThrottle = true;
|
||||
} else {
|
||||
clearTimeout(lastFn);
|
||||
lastFn = setTimeout(function() {
|
||||
if (Date.now() - lastTime >= wait) {
|
||||
fn.apply(context, args);
|
||||
lastTime = Date.now();
|
||||
}
|
||||
}, Math.max(wait - (Date.now() - lastTime), 0));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const getImageUrl = (path) => {
|
||||
const baseUrl = process.env.VUE_APP_BASE_URL;
|
||||
if (!path) return '';
|
||||
if (path.startsWith('http')) {
|
||||
return path.replace('https://test.m2pool.com', baseUrl);
|
||||
}
|
||||
return `${baseUrl}${path.startsWith('/') ? '' : '/'}${path}`;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// (function() {
|
||||
// window.addEventListener('storage', function(event) {
|
||||
// if (event.key === 'accountList') { // 将 'yourKey' 替换为存储数据的键
|
||||
// location.reload();
|
||||
// }
|
||||
// });
|
||||
// })();
|
||||
339
mining-pool/src/utils/request.js
Normal file
339
mining-pool/src/utils/request.js
Normal file
@@ -0,0 +1,339 @@
|
||||
import axios from 'axios'
|
||||
import errorCode from './errorCode'
|
||||
import { Notification, MessageBox, Message } from 'element-ui'
|
||||
import loadingManager from './loadingManager';
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: process.env.VUE_APP_BASE_API,
|
||||
// 超时
|
||||
timeout: 10000,
|
||||
})
|
||||
|
||||
// 网络错误相关配置
|
||||
const NETWORK_ERROR_THROTTLE_TIME = 5000; // 错误提示节流时间
|
||||
const RETRY_DELAY = 2000; // 重试间隔时间
|
||||
const MAX_RETRY_TIMES = 3; // 最大重试次数
|
||||
const RETRY_WINDOW = 60000; // 60秒重试窗口
|
||||
let lastNetworkErrorTime = 0; // 上次网络错误提示时间
|
||||
let pendingRequests = new Map();
|
||||
|
||||
|
||||
// 网络状态监听器
|
||||
window.addEventListener('online', () => {
|
||||
// 网络恢复时,重试所有待处理的请求
|
||||
const now = Date.now();
|
||||
const pendingPromises = [];
|
||||
|
||||
pendingRequests.forEach(async (request, key) => {
|
||||
if (now - request.timestamp <= RETRY_WINDOW) {
|
||||
try {
|
||||
// 获取新的响应数据
|
||||
const response = await service(request.config);
|
||||
pendingPromises.push(response);
|
||||
|
||||
// 执行请求特定的回调
|
||||
if (request.callback && typeof request.callback === 'function') {
|
||||
request.callback(response);
|
||||
}
|
||||
|
||||
// 处理特定类型的请求
|
||||
if (window.vm) {
|
||||
// 处理图表数据请求
|
||||
if (request.config.url.includes('getPoolPower') && response && response.data) {
|
||||
// 触发图表更新事件
|
||||
window.dispatchEvent(new CustomEvent('chart-data-updated', {
|
||||
detail: { type: 'poolPower', data: response.data }
|
||||
}));
|
||||
}
|
||||
else if (request.config.url.includes('getNetPower') && response && response.data) {
|
||||
window.dispatchEvent(new CustomEvent('chart-data-updated', {
|
||||
detail: { type: 'netPower', data: response.data }
|
||||
}));
|
||||
}
|
||||
else if (request.config.url.includes('getBlockInfo') && response && response.rows) {
|
||||
window.dispatchEvent(new CustomEvent('chart-data-updated', {
|
||||
detail: { type: 'blockInfo', data: response.rows }
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
pendingRequests.delete(key);
|
||||
} catch (error) {
|
||||
console.error('重试请求失败:', error);
|
||||
pendingRequests.delete(key);
|
||||
}
|
||||
} else {
|
||||
pendingRequests.delete(key);
|
||||
}
|
||||
});
|
||||
|
||||
// 等待所有请求完成
|
||||
Promise.allSettled(pendingPromises).then(() => {
|
||||
// 重置所有 loading 状态
|
||||
loadingManager.resetAllLoadingStates();
|
||||
// 触发网络重试完成事件
|
||||
window.dispatchEvent(new CustomEvent('network-retry-complete'));
|
||||
});
|
||||
|
||||
// 显示网络恢复提示
|
||||
if (window.vm && window.vm.$message) {
|
||||
window.vm.$message({
|
||||
message: window.vm.$i18n.t('home.networkReconnected') || '网络已重新连接,正在恢复数据...',
|
||||
type: 'success',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
if (window.vm && window.vm.$message) {
|
||||
window.vm.$message({
|
||||
message: window.vm.$i18n.t('home.networkOffline') || '网络连接已断开,系统将在恢复连接后自动重试',
|
||||
type: 'warning',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
service.defaults.retry = 2;// 重试次数
|
||||
service.defaults.retryDelay = 2000;
|
||||
service.defaults.shouldRetry = (error) => true
|
||||
|
||||
localStorage.setItem('superReportError', "")
|
||||
let superReportError = localStorage.getItem('superReportError')
|
||||
window.addEventListener("setItem", () => {
|
||||
superReportError = localStorage.getItem('superReportError')
|
||||
});
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use(config => {
|
||||
superReportError = ""
|
||||
// retryCount =0
|
||||
localStorage.setItem('superReportError', "")
|
||||
// 是否需要设置 token
|
||||
let token
|
||||
try {
|
||||
token = JSON.parse(localStorage.getItem('token'))
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
if (token) {
|
||||
config.headers['Authorization'] = token
|
||||
}
|
||||
|
||||
|
||||
if (config.method == 'get' && config.data) {
|
||||
config.params = config.data
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.method === 'get' && config.params) {
|
||||
let url = config.url + '?';
|
||||
for (const propName of Object.keys(config.params)) {
|
||||
const value = config.params[propName];
|
||||
var part = encodeURIComponent(propName) + "=";
|
||||
if (value !== null && typeof (value) !== "undefined") {
|
||||
if (typeof value === 'object') {
|
||||
for (const key of Object.keys(value)) {
|
||||
if (value[key] !== null && typeof (value[key]) !== 'undefined') {
|
||||
let params = propName + '[' + key + ']';
|
||||
let subPart = encodeURIComponent(params) + '=';
|
||||
url += subPart + encodeURIComponent(value[key]) + '&';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
url += part + encodeURIComponent(value) + "&";
|
||||
}
|
||||
}
|
||||
}
|
||||
url = url.slice(0, -1);
|
||||
config.params = {};
|
||||
config.url = url;
|
||||
}
|
||||
return config
|
||||
}, error => {
|
||||
Promise.reject(error)
|
||||
})
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(res => {
|
||||
// 未设置状态码则默认成功状态
|
||||
const code = res.data.code || 200;
|
||||
// 获取错误信息
|
||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
||||
if (code === 421) {
|
||||
localStorage.removeItem('token')
|
||||
// 系统状态已过期,请重新点击SUPPORT按钮进入
|
||||
superReportError = localStorage.getItem('superReportError')
|
||||
if (!superReportError) {
|
||||
superReportError = 421
|
||||
localStorage.setItem('superReportError', superReportError)
|
||||
MessageBox.confirm(window.vm.$i18n.t(`user.loginExpired`), window.vm.$i18n.t(`user.overduePrompt`), {
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: window.vm.$i18n.t(`user.login`),
|
||||
cancelButtonText: window.vm.$i18n.t(`user.Home`),
|
||||
// showCancelButton: false, // 隐藏取消按钮
|
||||
closeOnClickModal: false, // 点击空白处不关闭对话框
|
||||
showClose: false, // 隐藏关闭按钮
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
window.vm.$router.push("/login")
|
||||
localStorage.removeItem('token')
|
||||
}).catch(() => {
|
||||
window.vm.$router.push("/")
|
||||
localStorage.removeItem('token')
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
return Promise.reject('登录状态已过期')
|
||||
} else if (code >= 500 && !superReportError) {
|
||||
superReportError = 500
|
||||
localStorage.setItem('superReportError', superReportError)
|
||||
Message({
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: msg,
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
// throw msg; // 抛出错误,中断请求链并触发后续的错误处理逻辑
|
||||
// return Promise.reject(new Error(msg))
|
||||
} else if (code !== 200) {
|
||||
|
||||
|
||||
|
||||
Notification.error({
|
||||
title: msg
|
||||
})
|
||||
return Promise.reject('error')
|
||||
|
||||
} else {
|
||||
|
||||
return res.data
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
error => {
|
||||
|
||||
|
||||
|
||||
|
||||
let { message } = error;
|
||||
|
||||
if (message == "Network Error" || message.includes("timeout")) {
|
||||
if (!navigator.onLine) {
|
||||
// 断网状态,添加到重试队列
|
||||
const requestKey = JSON.stringify({
|
||||
url: error.config.url,
|
||||
method: error.config.method,
|
||||
params: error.config.params,
|
||||
data: error.config.data
|
||||
});
|
||||
|
||||
// 根据URL确定请求类型并记录回调
|
||||
let callback = null;
|
||||
if (error.config.url.includes('getPoolPower')) {
|
||||
callback = (data) => {
|
||||
if (window.vm) {
|
||||
// 清除loading状态
|
||||
window.vm.minerChartLoading = false;
|
||||
}
|
||||
};
|
||||
} else if (error.config.url.includes('getBlockInfo')) {
|
||||
callback = (data) => {
|
||||
if (window.vm) {
|
||||
window.vm.reportBlockLoading = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!pendingRequests.has(requestKey)) {
|
||||
pendingRequests.set(requestKey, {
|
||||
config: error.config,
|
||||
timestamp: Date.now(),
|
||||
retryCount: 0,
|
||||
callback: callback
|
||||
});
|
||||
|
||||
console.log('请求已加入断网重连队列:', error.config.url);
|
||||
}
|
||||
} else if ((error.config.retry > 0 && error.config)) {
|
||||
// 保留现有的重试逻辑
|
||||
error.config.retry--;
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(service(error.config));
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!superReportError) {
|
||||
superReportError = "error"
|
||||
localStorage.setItem('superReportError', superReportError)
|
||||
let { message } = error;
|
||||
if (message == "Network Error") {
|
||||
// message = "后端接口网络连接异常,请刷新重试";
|
||||
const now = Date.now();
|
||||
if (now - lastNetworkErrorTime > NETWORK_ERROR_THROTTLE_TIME) {
|
||||
lastNetworkErrorTime = now; // 更新最后提示时间
|
||||
Message({
|
||||
message: window.vm.$i18n.t(`home.NetworkError`),
|
||||
type: 'error',
|
||||
duration: 4 * 1000,
|
||||
showClose: true
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
else if (message.includes("timeout")) {
|
||||
// message = "系统接口请求超时,请刷新重试";
|
||||
Message({
|
||||
message: window.vm.$i18n.t(`home.requestTimeout`),
|
||||
type: 'error',
|
||||
duration: 5 * 1000,
|
||||
showClose: true
|
||||
})
|
||||
|
||||
}
|
||||
else if (message.includes("Request failed with status code")) {
|
||||
// message = "系统接口" + message.substr(message.length - 3) + "异常";
|
||||
Message({
|
||||
message: "系统接口" + message.substr(message.length - 3) + "异常",
|
||||
type: 'error',
|
||||
duration: 5 * 1000,
|
||||
showClose: true
|
||||
})
|
||||
} else {
|
||||
|
||||
Message({
|
||||
message: message,
|
||||
type: 'error',
|
||||
duration: 5 * 1000,
|
||||
showClose: true
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return Promise.reject(error)
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
export default service
|
||||
Reference in New Issue
Block a user