修复config.go中的URL错误

This commit is contained in:
Alex Yang
2025-11-24 22:39:23 +08:00
parent a59f655769
commit b4525678e7
14 changed files with 422 additions and 117393 deletions

View File

@@ -115,28 +115,71 @@ function fetchHostsCount() {
// 空实现,保留函数声明以避免引用错误
}
// 通用API请求函数
function apiRequest(endpoint, method = 'GET', data = null) {
// 通用API请求函数 - 添加错误处理和重试机制
function apiRequest(endpoint, method = 'GET', data = null, maxRetries = 3) {
const headers = {
'Content-Type': 'application/json'
};
const config = {
method,
headers
headers,
timeout: 10000, // 设置超时时间为10秒
};
if (data && (method === 'POST' || method === 'PUT' || method === 'DELETE')) {
config.body = JSON.stringify(data);
}
return fetch(`${API_BASE_URL}${endpoint}`, config)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
});
let retries = 0;
function makeRequest() {
return fetch(`${API_BASE_URL}${endpoint}`, config)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 检查响应是否完整
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
// 使用.text()先获取响应文本处理可能的JSON解析错误
return response.text().then(text => {
try {
return JSON.parse(text);
} catch (e) {
console.error('JSON解析错误:', e, '响应文本:', text);
// 针对ERR_INCOMPLETE_CHUNKED_ENCODING错误进行重试
if (retries < maxRetries) {
retries++;
console.warn(`请求失败,正在进行第${retries}次重试...`);
return new Promise(resolve => setTimeout(() => resolve(makeRequest()), 1000 * retries));
}
throw new Error('JSON解析失败且重试次数已达上限');
}
});
}
return response.json();
})
.catch(error => {
console.error('API请求错误:', error);
// 检查是否为网络错误或ERR_INCOMPLETE_CHUNKED_ENCODING相关错误
if ((error.name === 'TypeError' && error.message.includes('Failed to fetch')) ||
error.message.includes('incomplete chunked encoding')) {
if (retries < maxRetries) {
retries++;
console.warn(`网络错误,正在进行第${retries}次重试...`);
return new Promise(resolve => setTimeout(() => resolve(makeRequest()), 1000 * retries));
}
}
throw error;
});
}
return makeRequest();
}
// 数字格式化函数

View File

@@ -6,6 +6,67 @@ let domainDataCache = {
let domainUpdateTimer = null;
const DOMAIN_UPDATE_INTERVAL = 5000; // 域名排行更新间隔设为5秒比统计数据更新慢一些
// 初始化小型图表 - 修复Canvas重用问题
function initMiniCharts() {
// 获取所有图表容器
const chartContainers = document.querySelectorAll('.chart-card canvas');
// 全局图表实例存储
window.chartInstances = window.chartInstances || {};
chartContainers.forEach(canvas => {
// 获取图表数据属性
const chartId = canvas.id;
const chartType = canvas.dataset.chartType || 'line';
const chartData = JSON.parse(canvas.dataset.chartData || '{}');
// 设置图表上下文
const ctx = canvas.getContext('2d');
// 销毁已存在的图表实例避免Canvas重用错误
if (window.chartInstances[chartId]) {
window.chartInstances[chartId].destroy();
}
// 创建新图表
window.chartInstances[chartId] = new Chart(ctx, {
type: chartType,
data: chartData,
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
tooltip: {
backgroundColor: 'rgba(0, 0, 0, 0.7)',
padding: 10,
cornerRadius: 4
}
},
scales: {
x: {
grid: {
display: false
}
},
y: {
beginAtZero: true,
grid: {
color: 'rgba(0, 0, 0, 0.05)'
}
}
},
animation: {
duration: 1000,
easing: 'easeOutQuart'
}
}
});
});
}
// 初始化仪表盘面板
function initDashboardPanel() {
// 初始化小型图表
@@ -20,6 +81,60 @@ function initDashboardPanel() {
}
// 启动域名排行的独立更新
startDomainUpdate();
// 初始化响应式侧边栏
initResponsiveSidebar();
}
// 初始化响应式侧边栏
function initResponsiveSidebar() {
// 创建侧边栏切换按钮
const toggleBtn = document.createElement('button');
toggleBtn.className = 'sidebar-toggle';
toggleBtn.innerHTML = '<i class="fas fa-bars"></i>';
document.body.appendChild(toggleBtn);
// 侧边栏切换逻辑
toggleBtn.addEventListener('click', function() {
const sidebar = document.querySelector('.sidebar');
sidebar.classList.toggle('open');
// 更新按钮图标
const icon = toggleBtn.querySelector('i');
if (sidebar.classList.contains('open')) {
icon.className = 'fas fa-times';
} else {
icon.className = 'fas fa-bars';
}
});
// 在侧边栏打开时点击内容区域关闭侧边栏
const content = document.querySelector('.content');
content.addEventListener('click', function() {
const sidebar = document.querySelector('.sidebar');
const toggleBtn = document.querySelector('.sidebar-toggle');
if (sidebar.classList.contains('open') && window.innerWidth <= 768) {
sidebar.classList.remove('open');
if (toggleBtn) {
const icon = toggleBtn.querySelector('i');
icon.className = 'fas fa-bars';
}
}
});
// 窗口大小变化时调整侧边栏状态
window.addEventListener('resize', function() {
const sidebar = document.querySelector('.sidebar');
const toggleBtn = document.querySelector('.sidebar-toggle');
if (window.innerWidth > 768) {
sidebar.classList.remove('open');
if (toggleBtn) {
const icon = toggleBtn.querySelector('i');
icon.className = 'fas fa-bars';
}
}
});
}
// 加载仪表盘数据