XCAPI commited on
Commit
5a97d23
·
verified ·
1 Parent(s): 5c0488f

Upload 2 files

Browse files
Files changed (2) hide show
  1. admin.html +249 -0
  2. workers +2 -2
admin.html ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>代理端点管理</title>
5
+ <style>
6
+ body {
7
+ font-family: Arial, sans-serif;
8
+ max-width: 1000px;
9
+ margin: 20px auto;
10
+ padding: 0 20px;
11
+ }
12
+ .endpoint-group {
13
+ margin: 20px 0;
14
+ padding: 15px;
15
+ border: 1px solid #ddd;
16
+ border-radius: 8px;
17
+ }
18
+ .endpoint {
19
+ display: flex;
20
+ align-items: center;
21
+ margin: 10px 0;
22
+ padding: 10px;
23
+ border: 1px solid #eee;
24
+ border-radius: 4px;
25
+ background-color: #f9f9f9;
26
+ }
27
+ .endpoint input[type="text"] {
28
+ flex: 1;
29
+ margin-right: 10px;
30
+ padding: 8px;
31
+ border: 1px solid #ddd;
32
+ border-radius: 4px;
33
+ }
34
+ .endpoint input[type="number"] {
35
+ width: 80px;
36
+ margin: 0 10px;
37
+ padding: 8px;
38
+ border: 1px solid #ddd;
39
+ border-radius: 4px;
40
+ }
41
+ .endpoint input[type="checkbox"] {
42
+ margin: 0 10px;
43
+ transform: scale(1.2);
44
+ }
45
+ button {
46
+ padding: 8px 15px;
47
+ margin: 5px;
48
+ cursor: pointer;
49
+ border: none;
50
+ border-radius: 4px;
51
+ background-color: #4CAF50;
52
+ color: white;
53
+ }
54
+ button:hover {
55
+ background-color: #45a049;
56
+ }
57
+ button.delete {
58
+ background-color: #f44336;
59
+ }
60
+ button.delete:hover {
61
+ background-color: #da190b;
62
+ }
63
+ .status {
64
+ position: fixed;
65
+ top: 20px;
66
+ right: 20px;
67
+ padding: 15px;
68
+ border-radius: 4px;
69
+ display: none;
70
+ z-index: 1000;
71
+ }
72
+ .success {
73
+ background-color: #4CAF50;
74
+ color: white;
75
+ }
76
+ .error {
77
+ background-color: #f44336;
78
+ color: white;
79
+ }
80
+ h2 {
81
+ color: #333;
82
+ border-bottom: 2px solid #4CAF50;
83
+ padding-bottom: 10px;
84
+ }
85
+ .controls {
86
+ margin: 20px 0;
87
+ padding: 10px;
88
+ background-color: #f5f5f5;
89
+ border-radius: 4px;
90
+ text-align: right;
91
+ }
92
+ </style>
93
+ </head>
94
+ <body>
95
+ <h1>代理端点管理</h1>
96
+
97
+ <div class="endpoint-group">
98
+ <h2>Models 端点</h2>
99
+ <div id="modelsEndpoints"></div>
100
+ <button onclick="addEndpoint('models')">添加 Models 端点</button>
101
+ </div>
102
+
103
+ <div class="endpoint-group">
104
+ <h2>Chat 端点</h2>
105
+ <div id="chatEndpoints"></div>
106
+ <button onclick="addEndpoint('chat')">添加 Chat 端点</button>
107
+ </div>
108
+
109
+ <div class="controls">
110
+ <button onclick="saveConfig()">保存所有配置</button>
111
+ <button onclick="logout()" style="background-color: #f44336;">退出登录</button>
112
+ </div>
113
+
114
+ <div id="status" class="status"></div>
115
+
116
+ <script>
117
+ // 获取存储的密钥
118
+ let apiKey = localStorage.getItem('apiKey');
119
+
120
+ // 如果没有密钥,提示输入
121
+ if (!apiKey) {
122
+ apiKey = prompt('请输入访问密钥:');
123
+ if (apiKey) {
124
+ localStorage.setItem('apiKey', apiKey);
125
+ } else {
126
+ window.location.href = '/';
127
+ }
128
+ }
129
+
130
+ // 显示状态信息
131
+ function showStatus(message, isError = false) {
132
+ const status = document.getElementById('status');
133
+ status.textContent = message;
134
+ status.className = 'status ' + (isError ? 'error' : 'success');
135
+ status.style.display = 'block';
136
+ setTimeout(() => status.style.display = 'none', 3000);
137
+ }
138
+
139
+ // 添加端点
140
+ function addEndpoint(type, url = '', weight = 1, enabled = true) {
141
+ const container = document.getElementById(type + 'Endpoints');
142
+ const div = document.createElement('div');
143
+ div.className = 'endpoint';
144
+ div.innerHTML = `
145
+ <input type="text" placeholder="输入端点URL" value="${url}">
146
+ <input type="number" placeholder="权重" value="${weight}" min="1">
147
+ <label>
148
+ <input type="checkbox" ${enabled ? 'checked' : ''}>
149
+ 启用
150
+ </label>
151
+ <button class="delete" onclick="this.parentElement.remove()">删除</button>
152
+ `;
153
+ container.appendChild(div);
154
+ }
155
+
156
+ // 获取端点配置
157
+ function getEndpointsConfig(type) {
158
+ const endpoints = [];
159
+ document.querySelectorAll(`#${type}Endpoints .endpoint`).forEach(el => {
160
+ endpoints.push({
161
+ url: el.querySelector('input[type="text"]').value.trim(),
162
+ weight: parseInt(el.querySelector('input[type="number"]').value) || 1,
163
+ enabled: el.querySelector('input[type="checkbox"]').checked
164
+ });
165
+ });
166
+ return endpoints;
167
+ }
168
+
169
+ // 带认证的fetch
170
+ async function fetchWithAuth(url, options = {}) {
171
+ const headers = {
172
+ ...options.headers,
173
+ 'Authorization': apiKey
174
+ };
175
+
176
+ const response = await fetch(url, { ...options, headers });
177
+
178
+ if (response.status === 401) {
179
+ localStorage.removeItem('apiKey');
180
+ window.location.reload();
181
+ return null;
182
+ }
183
+
184
+ return response;
185
+ }
186
+
187
+ // 保存配置
188
+ async function saveConfig() {
189
+ const config = {
190
+ models: getEndpointsConfig('models'),
191
+ chat: getEndpointsConfig('chat')
192
+ };
193
+
194
+ try {
195
+ const response = await fetchWithAuth('/admin/config', {
196
+ method: 'POST',
197
+ headers: {'Content-Type': 'application/json'},
198
+ body: JSON.stringify(config)
199
+ });
200
+
201
+ if (!response) return;
202
+
203
+ if (response.ok) {
204
+ showStatus('配置已保存');
205
+ } else {
206
+ showStatus('保存失败: ' + await response.text(), true);
207
+ }
208
+ } catch (error) {
209
+ showStatus('保存失败: ' + error.message, true);
210
+ }
211
+ }
212
+
213
+ // 加载配置
214
+ async function loadConfig() {
215
+ try {
216
+ const response = await fetchWithAuth('/admin/config');
217
+ if (!response) return;
218
+
219
+ const config = await response.json();
220
+
221
+ // 清空现有配置
222
+ document.getElementById('modelsEndpoints').innerHTML = '';
223
+ document.getElementById('chatEndpoints').innerHTML = '';
224
+
225
+ // 加载Models端点
226
+ config.models.forEach(ep => {
227
+ addEndpoint('models', ep.url, ep.weight, ep.enabled);
228
+ });
229
+
230
+ // 加载Chat端点
231
+ config.chat.forEach(ep => {
232
+ addEndpoint('chat', ep.url, ep.weight, ep.enabled);
233
+ });
234
+ } catch (error) {
235
+ showStatus('加载配置失败: ' + error.message, true);
236
+ }
237
+ }
238
+
239
+ // 退出登录
240
+ function logout() {
241
+ localStorage.removeItem('apiKey');
242
+ window.location.reload();
243
+ }
244
+
245
+ // 页面加载时获取配置
246
+ document.addEventListener('DOMContentLoaded', loadConfig);
247
+ </script>
248
+ </body>
249
+ </html>
workers CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d126a375e83735a3909d3b4c358c13f068a1915e1825c161f8cef11c261bfc1d
3
- size 17029289
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:eb0114e86c62dfaa45447496004cae3c07412fe0d1a633aa77083f8dd51d764d
3
+ size 8681626