Spaces:
Running
Running
File size: 7,736 Bytes
1aa43d1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
/**
* HuggingFace 保活管理器 - 前端交互脚本
*/
// Toast 通知函数
function showToast(message, type = 'info') {
const container = document.getElementById('toast-container');
const toast = document.createElement('div');
toast.className = `toast toast-${type}`;
const icons = {
success: '<svg viewBox="0 0 24 24" fill="none"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" stroke="currentColor" stroke-width="2"/><polyline points="22,4 12,14.01 9,11.01" stroke="currentColor" stroke-width="2"/></svg>',
error: '<svg viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/><line x1="15" y1="9" x2="9" y2="15" stroke="currentColor" stroke-width="2"/><line x1="9" y1="9" x2="15" y2="15" stroke="currentColor" stroke-width="2"/></svg>',
warning: '<svg viewBox="0 0 24 24" fill="none"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" stroke="currentColor" stroke-width="2"/><line x1="12" y1="9" x2="12" y2="13" stroke="currentColor" stroke-width="2"/><line x1="12" y1="17" x2="12.01" y2="17" stroke="currentColor" stroke-width="2"/></svg>',
info: '<svg viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/><line x1="12" y1="16" x2="12" y2="12" stroke="currentColor" stroke-width="2"/><line x1="12" y1="8" x2="12.01" y2="8" stroke="currentColor" stroke-width="2"/></svg>'
};
toast.innerHTML = `
<span class="toast-icon">${icons[type] || icons.info}</span>
<span class="toast-message">${message}</span>
<button class="toast-close" onclick="this.parentElement.remove()">
<svg viewBox="0 0 24 24" fill="none"><line x1="18" y1="6" x2="6" y2="18" stroke="currentColor" stroke-width="2"/><line x1="6" y1="6" x2="18" y2="18" stroke="currentColor" stroke-width="2"/></svg>
</button>
`;
container.appendChild(toast);
// 自动移除
setTimeout(() => {
toast.classList.add('fade-out');
setTimeout(() => toast.remove(), 300);
}, 4000);
}
// 刷新页面
function refreshPage() {
location.reload();
}
// 添加URL
document.getElementById('add-url-form').addEventListener('submit', async (e) => {
e.preventDefault();
const urlInput = document.getElementById('url-input');
const nameInput = document.getElementById('name-input');
const btn = e.target.querySelector('button[type="submit"]');
const url = urlInput.value.trim();
const name = nameInput.value.trim();
if (!url) {
showToast('请输入URL地址', 'error');
return;
}
btn.disabled = true;
btn.innerHTML = '<span class="loading"></span> 添加中...';
try {
const response = await fetch('/api/urls', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url, name })
});
const data = await response.json();
if (response.ok) {
showToast('URL添加成功', 'success');
setTimeout(refreshPage, 500);
} else {
showToast(data.error || '添加失败', 'error');
}
} catch (error) {
showToast('网络错误,请重试', 'error');
} finally {
btn.disabled = false;
btn.innerHTML = '<svg viewBox="0 0 24 24" fill="none"><line x1="12" y1="5" x2="12" y2="19" stroke="currentColor" stroke-width="2"/><line x1="5" y1="12" x2="19" y2="12" stroke="currentColor" stroke-width="2"/></svg> 添加';
}
});
// 删除URL
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', async () => {
const index = btn.dataset.index;
if (!confirm('确定要删除这个URL吗?')) return;
btn.disabled = true;
try {
const response = await fetch(`/api/urls/${index}`, {
method: 'DELETE'
});
if (response.ok) {
showToast('删除成功', 'success');
setTimeout(refreshPage, 500);
} else {
showToast('删除失败', 'error');
}
} catch (error) {
showToast('网络错误', 'error');
} finally {
btn.disabled = false;
}
});
});
// Ping单个URL
document.querySelectorAll('.ping-btn').forEach(btn => {
btn.addEventListener('click', async () => {
const index = btn.dataset.index;
const urlItem = btn.closest('.url-item');
const urlName = urlItem.querySelector('.url-name').textContent;
btn.disabled = true;
btn.innerHTML = '<span class="loading"></span>';
try {
const response = await fetch(`/api/ping/${index}`, {
method: 'POST'
});
const data = await response.json();
if (data.result && data.result.status === 'success') {
showToast(`${urlName} 连接成功 (${data.result.code})`, 'success');
} else if (data.result && data.result.status === 'warning') {
showToast(`${urlName} 返回状态码: ${data.result.code}`, 'warning');
} else {
showToast(`${urlName} 连接失败: ${data.result?.message || '未知错误'}`, 'error');
}
} catch (error) {
showToast('网络错误', 'error');
} finally {
btn.disabled = false;
btn.innerHTML = '<svg viewBox="0 0 24 24" fill="none"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" stroke="currentColor" stroke-width="2"/><polyline points="22,4 12,14.01 9,11.01" stroke="currentColor" stroke-width="2"/></svg>';
}
});
});
// 全部保活
document.getElementById('ping-all-btn')?.addEventListener('click', async () => {
const btn = document.getElementById('ping-all-btn');
btn.disabled = true;
btn.innerHTML = '<span class="loading"></span> 执行中...';
showToast('正在执行保活任务...', 'info');
try {
const response = await fetch('/api/ping', {
method: 'POST'
});
const data = await response.json();
if (data.results) {
const successCount = data.results.filter(r => r.status === 'success').length;
showToast(`保活完成: ${successCount}/${data.results.length} 成功`,
successCount === data.results.length ? 'success' : 'warning');
setTimeout(refreshPage, 1000);
}
} catch (error) {
showToast('执行失败', 'error');
} finally {
btn.disabled = false;
btn.innerHTML = '<svg viewBox="0 0 24 24" fill="none"><path d="M23 4v6h-6M1 20v-6h6" stroke="currentColor" stroke-width="2"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" stroke="currentColor" stroke-width="2"/></svg> 立即全部保活';
}
});
// 清空日志
document.getElementById('clear-logs-btn')?.addEventListener('click', async () => {
if (!confirm('确定要清空所有日志吗?')) return;
try {
const response = await fetch('/api/logs', {
method: 'DELETE'
});
if (response.ok) {
showToast('日志已清空', 'success');
setTimeout(refreshPage, 500);
}
} catch (error) {
showToast('清空失败', 'error');
}
});
// 页面加载完成
document.addEventListener('DOMContentLoaded', () => {
console.log('HuggingFace 保活管理器已加载');
});
|