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

Delete index完美的样式.html

Browse files
Files changed (1) hide show
  1. index完美的样式.html +0 -517
index完美的样式.html DELETED
@@ -1,517 +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
- /* details {
156
- background-color: var(--search-result-background);
157
- color: var(--text-color);
158
- border-radius: 8px;
159
- padding: 10px;
160
- margin-bottom: 10px;
161
- transition: all 0.3s ease;
162
- border: 1px solid var(--border-color);
163
- }
164
- summary {
165
- cursor: pointer;
166
- font-weight: bold;
167
- color: var(--text-color);
168
- }
169
- details ul {
170
- list-style-type: none;
171
- padding-left: 0;
172
- }
173
- details li {
174
- background-color: var(--chat-bubble-ai);
175
- color: var(--text-color);
176
- padding: 10px;
177
- margin-top: 10px;
178
- border-radius: 4px;
179
- border: 1px solid var(--border-color);
180
- }
181
- details * {
182
- background-color: var(--search-result-background);
183
- } */
184
- .search-results {
185
- background-color: var(--search-result-background);
186
- color: var(--text-color);
187
- border: 1px solid var(--border-color);
188
- }
189
- .search-results summary {
190
- cursor: pointer;
191
- font-weight: bold;
192
- }
193
- .search-results ul {
194
- list-style-type: none;
195
- padding-left: 0;
196
- }
197
- .search-results li {
198
- background-color: var(--chat-bubble-ai);
199
- border: 1px solid var(--border-color);
200
- }
201
- /* 控制台消息条目样式 */
202
- #status-log div {
203
- background-color: var(--console-background);
204
- color: var(--console-text);
205
- border: 1px solid var(--border-color);
206
- }
207
- @media (max-width: 768px) {
208
- .sidebar {
209
- position: fixed;
210
- right: -300px;
211
- top: 0;
212
- bottom: 0;
213
- width: 300px;
214
- z-index: 1000;
215
- transition: right 0.3s ease-in-out;
216
- }
217
- .sidebar.open {
218
- right: 0;
219
- }
220
- .sidebar-overlay {
221
- display: none;
222
- position: fixed;
223
- top: 0;
224
- left: 0;
225
- right: 0;
226
- bottom: 0;
227
- background-color: rgba(0, 0, 0, 0.5);
228
- z-index: 999;
229
- }
230
- .sidebar-overlay.show {
231
- display: block;
232
- }
233
- }
234
- </style>
235
- </head>
236
- <body class="h-screen flex flex-col md:flex-row p-4">
237
- <!-- 主聊天窗口 -->
238
- <div class="chat-container flex-grow md:w-3/4 p-4 flex flex-col h-screen mr-4">
239
- <div id="chat-window" class="flex-grow overflow-y-auto mb-4 p-4 rounded-lg shadow-inner"></div>
240
- <div class="relative">
241
- <input id="user-input" type="text" class="w-full border p-2" placeholder="输入您的问题...">
242
- <button id="send-btn" class="text-2xl">
243
- <i class="fas fa-paper-plane"></i>
244
- </button>
245
- </div>
246
- </div>
247
-
248
- <!-- 右侧控制台 -->
249
- <div class="sidebar console md:w-1/4 p-4 h-screen overflow-y-auto">
250
- <h2 class="text-xl font-bold mb-4">运行状态</h2>
251
- <div class="mb-4">
252
- <div class="mb-2">
253
- <span class="status-indicator" id="main-model-status"></span>
254
- 主模型
255
- </div>
256
- <div class="mb-2">
257
- <span class="status-indicator" id="sub-model-status"></span>
258
- 次模型
259
- </div>
260
- <div class="mb-2">
261
- <span class="status-indicator" id="search-status"></span>
262
- 搜索
263
- </div>
264
- <div>
265
- <span class="status-indicator" id="email-status"></span>
266
- 邮件发送
267
- </div>
268
- </div>
269
- <div id="status-log" class="p-2 rounded h-64 overflow-y-auto mb-4"></div>
270
- <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">
271
- <i class="fas fa-cog"></i> 设置
272
- </button>
273
- </div>
274
-
275
- <!-- 移动端侧边栏切换按钮 -->
276
- <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">
277
- <i class="fas fa-bars"></i>
278
- </button>
279
-
280
- <!-- 移动端侧边栏遮罩 -->
281
- <div id="sidebar-overlay" class="sidebar-overlay"></div>
282
-
283
- <!-- 暗色模式切换按钮 -->
284
- <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">
285
- <i class="fas fa-moon"></i>
286
- </button>
287
-
288
- <!-- 设置对话框 -->
289
- <div id="settings-modal" class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden flex items-center justify-center z-50">
290
- <div class="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-xl">
291
- <h2 class="text-xl font-bold mb-4">设置</h2>
292
- <div class="mb-4">
293
- <label for="max-history" class="block mb-2">保留对话轮数:</label>
294
- <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">
295
- </div>
296
- <div class="flex justify-end">
297
- <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>
298
- <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>
299
- </div>
300
- </div>
301
- </div>
302
-
303
- <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
304
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
305
- <script>
306
- const chatWindow = document.getElementById('chat-window');
307
- const userInput = document.getElementById('user-input');
308
- const sendBtn = document.getElementById('send-btn');
309
- const mainModelStatus = document.getElementById('main-model-status');
310
- const subModelStatus = document.getElementById('sub-model-status');
311
- const searchStatus = document.getElementById('search-status');
312
- const emailStatus = document.getElementById('email-status');
313
- const statusLog = document.getElementById('status-log');
314
- const settingsBtn = document.getElementById('settings-btn');
315
- const settingsModal = document.getElementById('settings-modal');
316
- const saveSettingsBtn = document.getElementById('save-settings');
317
- const cancelSettingsBtn = document.getElementById('cancel-settings');
318
- const maxHistoryInput = document.getElementById('max-history');
319
- const darkModeToggle = document.getElementById('dark-mode-toggle');
320
- const sidebarToggle = document.getElementById('sidebar-toggle');
321
- const sidebar = document.querySelector('.sidebar');
322
- const sidebarOverlay = document.getElementById('sidebar-overlay');
323
- let conversationHistory = [];
324
- let maxHistory = 10;
325
- function addMessage(content, isUser) {
326
- const bubble = document.createElement('div');
327
- bubble.className = `chat-bubble ${isUser ? 'user-bubble' : 'ai-bubble'}`;
328
- bubble.innerHTML = isUser ? content : marked.parse(content);
329
- chatWindow.appendChild(bubble);
330
- chatWindow.scrollTop = chatWindow.scrollHeight;
331
-
332
- bubble.querySelectorAll('pre code').forEach((block) => {
333
- hljs.highlightBlock(block);
334
- });
335
-
336
- conversationHistory.push({
337
- role: isUser ? 'user' : 'assistant',
338
- content: content
339
- });
340
-
341
- if (conversationHistory.length > maxHistory * 2) {
342
- conversationHistory = conversationHistory.slice(-maxHistory * 2);
343
- }
344
- }
345
- function updateStatus(mainActive, subActive, searchActive, emailActive) {
346
- mainModelStatus.className = `status-indicator ${mainActive ? 'status-active' : 'status-inactive'}`;
347
- subModelStatus.className = `status-indicator ${subActive ? 'status-active' : 'status-inactive'}`;
348
- searchStatus.className = `status-indicator ${searchActive ? 'status-active' : 'status-inactive'}`;
349
- emailStatus.className = `status-indicator ${emailActive ? 'status-active' : 'status-inactive'}`;
350
- }
351
- function addStatusLog(message) {
352
- const logEntry = document.createElement('div');
353
- logEntry.className = 'mb-2 p-2 bg-white dark:bg-gray-700 rounded shadow';
354
- logEntry.textContent = message;
355
- statusLog.appendChild(logEntry);
356
- statusLog.scrollTop = statusLog.scrollHeight;
357
- }
358
- function displaySearchResults(results, type) {
359
- const searchResults = document.createElement('details');
360
- searchResults.className = 'search-results mb-2 p-2 rounded';
361
- const summary = document.createElement('summary');
362
- summary.textContent = type === 'papers' ? '论文搜索结果' : '搜索结果';
363
- searchResults.appendChild(summary);
364
- const resultsList = document.createElement('ul');
365
- resultsList.className = 'mt-2';
366
- results.forEach(result => {
367
- const li = document.createElement('li');
368
- li.className = 'mb-2 p-2 rounded';
369
- if (type === 'papers') {
370
- li.innerHTML = `
371
- <strong>标题:</strong> ${result.标题}<br>
372
- <strong>作者:</strong> ${result.作者}<br>
373
- <strong>DOI:</strong> ${result.DOI}<br>
374
- <strong>ISBN:</strong> ${result.ISBN}<br>
375
- <strong>摘要:</strong> ${result.摘要}
376
- `;
377
- } else {
378
- li.innerHTML = `<strong>${result.title}</strong><br>${result.body}`;
379
- }
380
- resultsList.appendChild(li);
381
- });
382
- searchResults.appendChild(resultsList);
383
- chatWindow.appendChild(searchResults);
384
- }
385
- async function sendMessage() {
386
- const question = userInput.value.trim();
387
- if (!question) return;
388
- addMessage(question, true);
389
- userInput.value = '';
390
- updateStatus(false, false, false, false);
391
- statusLog.innerHTML = '';
392
- addStatusLog('开始处理问题...');
393
- try {
394
- const response = await fetch('/chat', {
395
- method: 'POST',
396
- headers: {
397
- 'Content-Type': 'application/json'
398
- },
399
- body: JSON.stringify({
400
- question,
401
- history: conversationHistory.slice(-maxHistory * 2 + 1)
402
- })
403
- });
404
- const data = await response.json();
405
- data.status_log.forEach(log => addStatusLog(log));
406
- updateStatus(true, true, data.search_used, data.email_sent);
407
- if (data.search_used) {
408
- if (Array.isArray(data.search_results) && data.search_results.length > 0 && 'DOI' in data.search_results[0]) {
409
- displaySearchResults(data.search_results, 'papers');
410
- } else {
411
- displaySearchResults(data.search_results, 'web');
412
- }
413
- }
414
- addMessage(data.response, false);
415
- addStatusLog('回答完成');
416
- } catch (error) {
417
- console.error('Error:', error);
418
- addMessage('发生错误,请稍后再试。', false);
419
- updateStatus(false, false, false, false);
420
- addStatusLog('发生错误');
421
- }
422
- }
423
- sendBtn.addEventListener('click', sendMessage);
424
- userInput.addEventListener('keypress', (e) => {
425
- if (e.key === 'Enter') {
426
- sendMessage();
427
- }
428
- });
429
- // 设置相关功能
430
- settingsBtn.addEventListener('click', () => {
431
- settingsModal.classList.remove('hidden');
432
- maxHistoryInput.value = maxHistory;
433
- });
434
- saveSettingsBtn.addEventListener('click', async () => {
435
- const newMaxHistory = parseInt(maxHistoryInput.value);
436
- if (newMaxHistory >= 1 && newMaxHistory <= 50) {
437
- maxHistory = newMaxHistory;
438
- try {
439
- const response = await fetch('/settings', {
440
- method: 'POST',
441
- headers: {
442
- 'Content-Type': 'application/json'
443
- },
444
- body: JSON.stringify({ max_history: maxHistory })
445
- });
446
- const data = await response.json();
447
- if (data.status === 'success') {
448
- alert('设置已保存');
449
- } else {
450
- alert('保存设置时出错');
451
- }
452
- } catch (error) {
453
- console.error('Error:', error);
454
- alert('保存设置时出错');
455
- }
456
- settingsModal.classList.add('hidden');
457
- } else {
458
- alert('请输入1到50之间的数字');
459
- }
460
- });
461
- cancelSettingsBtn.addEventListener('click', () => {
462
- settingsModal.classList.add('hidden');
463
- });
464
- // 暗色模式切换
465
- darkModeToggle.addEventListener('click', () => {
466
- document.body.classList.toggle('dark-mode');
467
- updateDarkModeIcon();
468
- });
469
- function updateDarkModeIcon() {
470
- const icon = darkModeToggle.querySelector('i');
471
- if (document.body.classList.contains('dark-mode')) {
472
- icon.classList.remove('fa-moon');
473
- icon.classList.add('fa-sun');
474
- } else {
475
- icon.classList.remove('fa-sun');
476
- icon.classList.add('fa-moon');
477
- }
478
- }
479
- // 初始化暗色模式
480
- function initDarkMode() {
481
- if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
482
- document.body.classList.add('dark-mode');
483
- }
484
- updateDarkModeIcon();
485
- }
486
- // 监听系统主题变化
487
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
488
- if (e.matches) {
489
- document.body.classList.add('dark-mode');
490
- } else {
491
- document.body.classList.remove('dark-mode');
492
- }
493
- updateDarkModeIcon();
494
- });
495
- // 侧边栏控制
496
- sidebarToggle.addEventListener('click', () => {
497
- sidebar.classList.toggle('open');
498
- sidebarOverlay.classList.toggle('show');
499
- });
500
- sidebarOverlay.addEventListener('click', () => {
501
- sidebar.classList.remove('open');
502
- sidebarOverlay.classList.remove('show');
503
- });
504
- // 页面加载完成后初始化
505
- window.addEventListener('load', () => {
506
- initDarkMode();
507
- });
508
- // 监听窗口大小变化,在大屏幕时关闭侧边栏遮罩
509
- window.addEventListener('resize', () => {
510
- if (window.innerWidth >= 768) {
511
- sidebar.classList.remove('open');
512
- sidebarOverlay.classList.remove('show');
513
- }
514
- });
515
- </script>
516
- </body>
517
- </html>