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 保活管理器已加载');
});