mistpe commited on
Commit
7b4a123
1 Parent(s): e45cd7b

Delete index.html

Browse files
Files changed (1) hide show
  1. index.html +0 -489
index.html DELETED
@@ -1,489 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>AI 对话系统</title>
7
- <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
8
- <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
9
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css">
10
- <style>
11
- :root {
12
- --primary-color: #3498db;
13
- --secondary-color: #2ecc71;
14
- --background-color: #f5f5f5;
15
- --chat-background: #ffffff;
16
- --text-color: #333333;
17
- --chat-bubble-user: #e8f5fe;
18
- --chat-bubble-ai: #f0f0f0;
19
- --sidebar-background: #ffffff;
20
- --input-background: #ffffff;
21
- --send-button-color: #4CAF50;
22
- --console-background: #f8f9fa;
23
- --console-text: #495057;
24
- --fold-background: #f8f9fa;
25
- --fold-text: #495057;
26
- --border-color: transparent;
27
- --search-result-background: #f8f9fa;
28
- }
29
- .dark-mode {
30
- --primary-color: #3498db;
31
- --secondary-color: #2ecc71;
32
- --background-color: #1e2124;
33
- --chat-background: #36393f;
34
- --text-color: #dcddde;
35
- --chat-bubble-user: #4e5d94;
36
- --chat-bubble-ai: #40444b;
37
- --sidebar-background: #2f3136;
38
- --input-background: #40444b;
39
- --send-button-color: #7289da;
40
- --console-background: #2f3136;
41
- --console-text: #dcddde;
42
- --fold-background: #2f3136;
43
- --fold-text: #dcddde;
44
- --border-color: #ffffff;
45
- --search-result-background: #2f3136;
46
- }
47
- body {
48
- background-color: var(--background-color);
49
- color: var(--text-color);
50
- transition: all 0.3s ease;
51
- }
52
- .chat-container {
53
- background-color: var(--chat-background);
54
- transition: all 0.3s ease;
55
- border-radius: 8px;
56
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
57
- }
58
- .chat-bubble {
59
- max-width: 80%;
60
- padding: 12px;
61
- border-radius: 12px;
62
- margin-bottom: 12px;
63
- box-shadow: 0 1px 2px rgba(0,0,0,0.1);
64
- transition: all 0.3s ease;
65
- }
66
- .user-bubble {
67
- background-color: var(--chat-bubble-user);
68
- color: var(--text-color);
69
- margin-left: auto;
70
- border-bottom-right-radius: 4px;
71
- }
72
- .ai-bubble {
73
- background-color: var(--chat-bubble-ai);
74
- color: var(--text-color);
75
- margin-right: auto;
76
- border-bottom-left-radius: 4px;
77
- }
78
- .dark-mode .chat-bubble {
79
- border: 1px solid var(--border-color);
80
- }
81
- .status-indicator {
82
- width: 12px;
83
- height: 12px;
84
- border-radius: 50%;
85
- display: inline-block;
86
- margin-right: 8px;
87
- transition: all 0.3s ease;
88
- }
89
- .status-active {
90
- background-color: var(--secondary-color);
91
- }
92
- .status-inactive {
93
- background-color: #95a5a6;
94
- }
95
- .sidebar {
96
- background-color: var(--sidebar-background);
97
- transition: all 0.3s ease;
98
- border-radius: 8px;
99
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
100
- }
101
- #user-input {
102
- background-color: var(--input-background);
103
- color: var(--text-color);
104
- transition: all 0.3s ease;
105
- border-radius: 8px;
106
- padding-right: 40px;
107
- }
108
- #send-btn {
109
- position: absolute;
110
- right: 10px;
111
- top: 50%;
112
- transform: translateY(-50%);
113
- background: none;
114
- border: none;
115
- color: var(--send-button-color);
116
- font-size: 20px;
117
- cursor: pointer;
118
- transition: all 0.3s ease;
119
- }
120
- #send-btn:hover {
121
- opacity: 0.8;
122
- }
123
- .console {
124
- background-color: var(--console-background);
125
- color: var(--console-text);
126
- transition: all 0.3s ease;
127
- border-radius: 8px;
128
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
129
- }
130
- #status-log {
131
- background-color: var(--console-background);
132
- color: var(--console-text);
133
- transition: all 0.3s ease;
134
- border: 1px solid var(--border-color);
135
- }
136
- /* 滚动条样式 */
137
- ::-webkit-scrollbar {
138
- width: 8px;
139
- }
140
- ::-webkit-scrollbar-track {
141
- background: var(--chat-background);
142
- }
143
- ::-webkit-scrollbar-thumb {
144
- background: var(--primary-color);
145
- border-radius: 4px;
146
- }
147
- ::-webkit-scrollbar-thumb:hover {
148
- background: var(--secondary-color);
149
- }
150
- /* 代码块样式 */
151
- .hljs {
152
- background: var(--fold-background) !important;
153
- color: var(--fold-text) !important;
154
- }
155
-
156
- .search-results {
157
- background-color: var(--search-result-background);
158
- color: var(--text-color);
159
- border: 1px solid var(--border-color);
160
- }
161
- .search-results summary {
162
- cursor: pointer;
163
- font-weight: bold;
164
- }
165
- .search-results ul {
166
- list-style-type: none;
167
- padding-left: 0;
168
- }
169
- .search-results li {
170
- background-color: var(--chat-bubble-ai);
171
- border: 1px solid var(--border-color);
172
- }
173
- /* 控制台消息条目样式 */
174
- #status-log div {
175
- background-color: var(--console-background);
176
- color: var(--console-text);
177
- border: 1px solid var(--border-color);
178
- }
179
- @media (max-width: 768px) {
180
- .sidebar {
181
- position: fixed;
182
- right: -300px;
183
- top: 0;
184
- bottom: 0;
185
- width: 300px;
186
- z-index: 1000;
187
- transition: right 0.3s ease-in-out;
188
- }
189
- .sidebar.open {
190
- right: 0;
191
- }
192
- .sidebar-overlay {
193
- display: none;
194
- position: fixed;
195
- top: 0;
196
- left: 0;
197
- right: 0;
198
- bottom: 0;
199
- background-color: rgba(0, 0, 0, 0.5);
200
- z-index: 999;
201
- }
202
- .sidebar-overlay.show {
203
- display: block;
204
- }
205
- }
206
- </style>
207
- </head>
208
- <body class="h-screen flex flex-col md:flex-row p-4">
209
- <!-- 主聊天窗口 -->
210
- <div class="chat-container flex-grow md:w-3/4 p-4 flex flex-col h-screen mr-4">
211
- <div id="chat-window" class="flex-grow overflow-y-auto mb-4 p-4 rounded-lg shadow-inner"></div>
212
- <div class="relative">
213
- <input id="user-input" type="text" class="w-full border p-2" placeholder="输入您的问题...">
214
- <button id="send-btn" class="text-2xl">
215
- <i class="fas fa-paper-plane"></i>
216
- </button>
217
- </div>
218
- </div>
219
-
220
- <!-- 右侧控制台 -->
221
- <div class="sidebar console md:w-1/4 p-4 h-screen overflow-y-auto">
222
- <h2 class="text-xl font-bold mb-4">运行状态</h2>
223
- <div class="mb-4">
224
- <div class="mb-2">
225
- <span class="status-indicator" id="main-model-status"></span>
226
- 主模型
227
- </div>
228
- <div class="mb-2">
229
- <span class="status-indicator" id="sub-model-status"></span>
230
- 次模型
231
- </div>
232
- <div class="mb-2">
233
- <span class="status-indicator" id="search-status"></span>
234
- 搜索
235
- </div>
236
- <div>
237
- <span class="status-indicator" id="email-status"></span>
238
- 邮件发送
239
- </div>
240
- </div>
241
- <div id="status-log" class="p-2 rounded h-64 overflow-y-auto mb-4"></div>
242
- <button id="settings-btn" class="w-full bg-gray-300 dark:bg-gray-600 text-gray-800 dark:text-white px-4 py-2 rounded hover:bg-gray-400 dark:hover:bg-gray-500 transition duration-200">
243
- <i class="fas fa-cog"></i> 设置
244
- </button>
245
- </div>
246
-
247
- <!-- 移动端侧边栏切换按钮 -->
248
- <button id="sidebar-toggle" class="md:hidden fixed top-4 right-4 bg-gray-300 dark:bg-gray-600 text-gray-800 dark:text-white p-2 rounded-full shadow-lg hover:bg-gray-400 dark:hover:bg-gray-500 transition duration-200 z-50">
249
- <i class="fas fa-bars"></i>
250
- </button>
251
-
252
- <!-- 移动端侧边栏遮罩 -->
253
- <div id="sidebar-overlay" class="sidebar-overlay"></div>
254
-
255
- <!-- 暗色模式切换按钮 -->
256
- <button id="dark-mode-toggle" class="fixed top-4 left-4 bg-gray-300 dark:bg-gray-600 text-gray-800 dark:text-white p-2 rounded-full shadow-lg hover:bg-gray-400 dark:hover:bg-gray-500 transition duration-200">
257
- <i class="fas fa-moon"></i>
258
- </button>
259
-
260
- <!-- 设置对话框 -->
261
- <div id="settings-modal" class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden flex items-center justify-center z-50">
262
- <div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-xl">
263
- <h2 class="text-xl font-bold mb-4">设置</h2>
264
- <div class="mb-4">
265
- <label for="max-history" class="block mb-2">保留对话轮数:</label>
266
- <input type="number" id="max-history" class="border rounded p-2 w-full dark:bg-gray-700 dark:text-white" min="1" max="50" value="10">
267
- </div>
268
- <div class="flex justify-end">
269
- <button id="save-settings" class="bg-blue-500 text-white px-4 py-2 rounded mr-2 hover:bg-blue-600 transition duration-200">保存</button>
270
- <button id="cancel-settings" class="bg-gray-300 dark:bg-gray-600 text-gray-800 dark:text-white px-4 py-2 rounded hover:bg-gray-400 dark:hover:bg-gray-500 transition duration-200">取消</button>
271
- </div>
272
- </div>
273
- </div>
274
-
275
- <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
276
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
277
- <script>
278
- const chatWindow = document.getElementById('chat-window');
279
- const userInput = document.getElementById('user-input');
280
- const sendBtn = document.getElementById('send-btn');
281
- const mainModelStatus = document.getElementById('main-model-status');
282
- const subModelStatus = document.getElementById('sub-model-status');
283
- const searchStatus = document.getElementById('search-status');
284
- const emailStatus = document.getElementById('email-status');
285
- const statusLog = document.getElementById('status-log');
286
- const settingsBtn = document.getElementById('settings-btn');
287
- const settingsModal = document.getElementById('settings-modal');
288
- const saveSettingsBtn = document.getElementById('save-settings');
289
- const cancelSettingsBtn = document.getElementById('cancel-settings');
290
- const maxHistoryInput = document.getElementById('max-history');
291
- const darkModeToggle = document.getElementById('dark-mode-toggle');
292
- const sidebarToggle = document.getElementById('sidebar-toggle');
293
- const sidebar = document.querySelector('.sidebar');
294
- const sidebarOverlay = document.getElementById('sidebar-overlay');
295
- let conversationHistory = [];
296
- let maxHistory = 10;
297
- function addMessage(content, isUser) {
298
- const bubble = document.createElement('div');
299
- bubble.className = `chat-bubble ${isUser ? 'user-bubble' : 'ai-bubble'}`;
300
- bubble.innerHTML = isUser ? content : marked.parse(content);
301
- chatWindow.appendChild(bubble);
302
- chatWindow.scrollTop = chatWindow.scrollHeight;
303
-
304
- bubble.querySelectorAll('pre code').forEach((block) => {
305
- hljs.highlightBlock(block);
306
- });
307
-
308
- conversationHistory.push({
309
- role: isUser ? 'user' : 'assistant',
310
- content: content
311
- });
312
-
313
- if (conversationHistory.length > maxHistory * 2) {
314
- conversationHistory = conversationHistory.slice(-maxHistory * 2);
315
- }
316
- }
317
- function updateStatus(mainActive, subActive, searchActive, emailActive) {
318
- mainModelStatus.className = `status-indicator ${mainActive ? 'status-active' : 'status-inactive'}`;
319
- subModelStatus.className = `status-indicator ${subActive ? 'status-active' : 'status-inactive'}`;
320
- searchStatus.className = `status-indicator ${searchActive ? 'status-active' : 'status-inactive'}`;
321
- emailStatus.className = `status-indicator ${emailActive ? 'status-active' : 'status-inactive'}`;
322
- }
323
- function addStatusLog(message) {
324
- const logEntry = document.createElement('div');
325
- logEntry.className = 'mb-2 p-2 bg-white dark:bg-gray-700 rounded shadow';
326
- logEntry.textContent = message;
327
- statusLog.appendChild(logEntry);
328
- statusLog.scrollTop = statusLog.scrollHeight;
329
- }
330
- function displaySearchResults(results, type) {
331
- const searchResults = document.createElement('details');
332
- searchResults.className = 'search-results mb-2 p-2 rounded';
333
- const summary = document.createElement('summary');
334
- summary.textContent = type === 'papers' ? '论文搜索结果' : '搜索结果';
335
- searchResults.appendChild(summary);
336
- const resultsList = document.createElement('ul');
337
- resultsList.className = 'mt-2';
338
- results.forEach(result => {
339
- const li = document.createElement('li');
340
- li.className = 'mb-2 p-2 rounded';
341
- if (type === 'papers') {
342
- li.innerHTML = `
343
- <strong>标题:</strong> ${result.标题}<br>
344
- <strong>作者:</strong> ${result.作者}<br>
345
- <strong>DOI:</strong> ${result.DOI}<br>
346
- <strong>ISBN:</strong> ${result.ISBN}<br>
347
- <strong>摘要:</strong> ${result.摘要}
348
- `;
349
- } else {
350
- li.innerHTML = `<strong>${result.title}</strong><br>${result.body}`;
351
- }
352
- resultsList.appendChild(li);
353
- });
354
- searchResults.appendChild(resultsList);
355
- chatWindow.appendChild(searchResults);
356
- }
357
- async function sendMessage() {
358
- const question = userInput.value.trim();
359
- if (!question) return;
360
- addMessage(question, true);
361
- userInput.value = '';
362
- updateStatus(false, false, false, false);
363
- statusLog.innerHTML = '';
364
- addStatusLog('开始处理问题...');
365
- try {
366
- const response = await fetch('/chat', {
367
- method: 'POST',
368
- headers: {
369
- 'Content-Type': 'application/json'
370
- },
371
- body: JSON.stringify({
372
- question,
373
- history: conversationHistory.slice(-maxHistory * 2 + 1)
374
- })
375
- });
376
- const data = await response.json();
377
- data.status_log.forEach(log => addStatusLog(log));
378
- updateStatus(true, true, data.search_used, data.email_sent);
379
- if (data.search_used) {
380
- if (Array.isArray(data.search_results) && data.search_results.length > 0 && 'DOI' in data.search_results[0]) {
381
- displaySearchResults(data.search_results, 'papers');
382
- } else {
383
- displaySearchResults(data.search_results, 'web');
384
- }
385
- }
386
- addMessage(data.response, false);
387
- addStatusLog('回答完成');
388
- } catch (error) {
389
- console.error('Error:', error);
390
- addMessage('发生错误,请稍后再试。', false);
391
- updateStatus(false, false, false, false);
392
- addStatusLog('发生错误');
393
- }
394
- }
395
- sendBtn.addEventListener('click', sendMessage);
396
- userInput.addEventListener('keypress', (e) => {
397
- if (e.key === 'Enter') {
398
- sendMessage();
399
- }
400
- });
401
- // 设置相关功能
402
- settingsBtn.addEventListener('click', () => {
403
- settingsModal.classList.remove('hidden');
404
- maxHistoryInput.value = maxHistory;
405
- });
406
- saveSettingsBtn.addEventListener('click', async () => {
407
- const newMaxHistory = parseInt(maxHistoryInput.value);
408
- if (newMaxHistory >= 1 && newMaxHistory <= 50) {
409
- maxHistory = newMaxHistory;
410
- try {
411
- const response = await fetch('/settings', {
412
- method: 'POST',
413
- headers: {
414
- 'Content-Type': 'application/json'
415
- },
416
- body: JSON.stringify({ max_history: maxHistory })
417
- });
418
- const data = await response.json();
419
- if (data.status === 'success') {
420
- alert('设置已保存');
421
- } else {
422
- alert('保存设置时出错');
423
- }
424
- } catch (error) {
425
- console.error('Error:', error);
426
- alert('保存设置时出错');
427
- }
428
- settingsModal.classList.add('hidden');
429
- } else {
430
- alert('请输入1到50之间的数字');
431
- }
432
- });
433
- cancelSettingsBtn.addEventListener('click', () => {
434
- settingsModal.classList.add('hidden');
435
- });
436
- // 暗色模式切换
437
- darkModeToggle.addEventListener('click', () => {
438
- document.body.classList.toggle('dark-mode');
439
- updateDarkModeIcon();
440
- });
441
- function updateDarkModeIcon() {
442
- const icon = darkModeToggle.querySelector('i');
443
- if (document.body.classList.contains('dark-mode')) {
444
- icon.classList.remove('fa-moon');
445
- icon.classList.add('fa-sun');
446
- } else {
447
- icon.classList.remove('fa-sun');
448
- icon.classList.add('fa-moon');
449
- }
450
- }
451
- // 初始化暗色模式
452
- function initDarkMode() {
453
- if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
454
- document.body.classList.add('dark-mode');
455
- }
456
- updateDarkModeIcon();
457
- }
458
- // 监听系统主题变化
459
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
460
- if (e.matches) {
461
- document.body.classList.add('dark-mode');
462
- } else {
463
- document.body.classList.remove('dark-mode');
464
- }
465
- updateDarkModeIcon();
466
- });
467
- // 侧边栏控制
468
- sidebarToggle.addEventListener('click', () => {
469
- sidebar.classList.toggle('open');
470
- sidebarOverlay.classList.toggle('show');
471
- });
472
- sidebarOverlay.addEventListener('click', () => {
473
- sidebar.classList.remove('open');
474
- sidebarOverlay.classList.remove('show');
475
- });
476
- // 页面加载完成后初始化
477
- window.addEventListener('load', () => {
478
- initDarkMode();
479
- });
480
- // 监听窗口大小变化,在大屏幕时关闭侧边栏遮罩
481
- window.addEventListener('resize', () => {
482
- if (window.innerWidth >= 768) {
483
- sidebar.classList.remove('open');
484
- sidebarOverlay.classList.remove('show');
485
- }
486
- });
487
- </script>
488
- </body>
489
- </html>