moelove commited on
Commit
ee61dec
·
1 Parent(s): 5def997

Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>

Files changed (3) hide show
  1. src/App.jsx +84 -27
  2. src/components/ChatList.jsx +1 -1
  3. src/index.css +353 -103
src/App.jsx CHANGED
@@ -7,13 +7,16 @@ import useLocalStorage from './hooks/useLocalStorage';
7
  function App() {
8
  const [settings, setSettings] = useLocalStorage('settings', {
9
  apiEndpoint: '',
10
- apiKey: ''
 
11
  });
12
 
13
  const [chats, setChats] = useLocalStorage('chats', []);
14
  const [currentChatId, setCurrentChatId] = useState(null);
15
  const [error, setError] = useState(null);
16
  const [loading, setLoading] = useState(false);
 
 
17
 
18
  const createNewChat = () => {
19
  const newChat = {
@@ -32,37 +35,91 @@ function App() {
32
  }
33
  };
34
 
 
 
 
 
 
 
 
 
35
  return (
36
  <div className="app-container">
37
- <div className="sidebar">
38
- <ChatList
39
- chats={chats}
40
- currentChat={chats.find(c => c.id === currentChatId)}
41
- onSelectChat={setCurrentChatId}
42
- onDeleteChat={deleteChat}
43
- onCreateNewChat={createNewChat}
44
- />
45
- <div className="settings-wrapper">
46
- <Settings
47
- settings={settings}
48
- onSave={setSettings}
49
- setSettings={setSettings}
50
- />
51
- </div>
52
  </div>
53
- <div className="main-content">
54
- {currentChatId && (
55
- <ChatWindow
56
- chat={chats.find(c => c.id === currentChatId)}
57
- settings={settings}
58
- onUpdateChat={(updatedChat) => {
59
- setChats(chats.map(c =>
60
- c.id === updatedChat.id ? updatedChat : c
61
- ));
62
- }}
 
 
 
 
 
 
 
 
 
63
  />
64
- )}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  {error && (
67
  <div className="error-message">
68
  Error: {error}
 
7
  function App() {
8
  const [settings, setSettings] = useLocalStorage('settings', {
9
  apiEndpoint: '',
10
+ apiKey: '',
11
+ model: 'DeepSeek-R1'
12
  });
13
 
14
  const [chats, setChats] = useLocalStorage('chats', []);
15
  const [currentChatId, setCurrentChatId] = useState(null);
16
  const [error, setError] = useState(null);
17
  const [loading, setLoading] = useState(false);
18
+ const [showSettings, setShowSettings] = useState(false);
19
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
20
 
21
  const createNewChat = () => {
22
  const newChat = {
 
35
  }
36
  };
37
 
38
+ const toggleSettings = () => {
39
+ setShowSettings(!showSettings);
40
+ };
41
+
42
+ const toggleSidebar = () => {
43
+ setSidebarCollapsed(!sidebarCollapsed);
44
+ };
45
+
46
  return (
47
  <div className="app-container">
48
+ <div className="app-header">
49
+ <h1 className="app-title">Thinking Model Client</h1>
50
+ <button
51
+ className="settings-button"
52
+ onClick={toggleSettings}
53
+ >
54
+ Settings
55
+ </button>
 
 
 
 
 
 
 
56
  </div>
57
+
58
+ <div className="app-content">
59
+ <div className={`sidebar ${sidebarCollapsed ? 'collapsed' : ''}`}>
60
+ <div className="sidebar-header">
61
+ <h2>Conversations</h2>
62
+ <button
63
+ className="toggle-sidebar-button"
64
+ onClick={toggleSidebar}
65
+ >
66
+ {sidebarCollapsed ? '→' : '←'}
67
+ </button>
68
+ </div>
69
+ <ChatList
70
+ chats={chats}
71
+ currentChat={chats.find(c => c.id === currentChatId)}
72
+ onSelectChat={setCurrentChatId}
73
+ onDeleteChat={deleteChat}
74
+ onCreateNewChat={createNewChat}
75
+ collapsed={sidebarCollapsed}
76
  />
77
+ </div>
78
+
79
+ <div className="main-content">
80
+ {currentChatId ? (
81
+ <ChatWindow
82
+ chat={chats.find(c => c.id === currentChatId)}
83
+ settings={settings}
84
+ onUpdateChat={(updatedChat) => {
85
+ setChats(chats.map(c =>
86
+ c.id === updatedChat.id ? updatedChat : c
87
+ ));
88
+ }}
89
+ />
90
+ ) : (
91
+ <div className="welcome-screen">
92
+ <h2>Welcome to Thinking Model Client</h2>
93
+ <p>Start a new conversation or select an existing one.</p>
94
+ <button className="new-chat-button" onClick={createNewChat}>
95
+ Start New Conversation
96
+ </button>
97
+ </div>
98
+ )}
99
+ </div>
100
  </div>
101
+
102
+ {showSettings && (
103
+ <div className="settings-overlay">
104
+ <div className="settings-modal">
105
+ <button
106
+ className="close-settings-button"
107
+ onClick={toggleSettings}
108
+ >
109
+ ×
110
+ </button>
111
+ <Settings
112
+ settings={settings}
113
+ onSave={(newSettings) => {
114
+ setSettings(newSettings);
115
+ setShowSettings(false);
116
+ }}
117
+ setSettings={setSettings}
118
+ />
119
+ </div>
120
+ </div>
121
+ )}
122
+
123
  {error && (
124
  <div className="error-message">
125
  Error: {error}
src/components/ChatList.jsx CHANGED
@@ -1,6 +1,6 @@
1
  import React from 'react';
2
 
3
- function ChatList({ chats, currentChat, onSelectChat, onDeleteChat, onCreateNewChat }) {
4
  return (
5
  <div className="chat-list">
6
  <h2>Conversations</h2>
 
1
  import React from 'react';
2
 
3
+ function ChatList({ chats, currentChat, onSelectChat, onDeleteChat, onCreateNewChat, collapsed }) {
4
  return (
5
  <div className="chat-list">
6
  <h2>Conversations</h2>
src/index.css CHANGED
@@ -150,11 +150,8 @@
150
 
151
  .message-content {
152
  padding: 12px 16px;
153
- border-radius: 12px;
154
- font-size: 14px;
155
- line-height: 1.5;
156
- width: fit-content;
157
- max-width: 100%;
158
  }
159
 
160
  .content-text {
@@ -168,8 +165,11 @@
168
  }
169
 
170
  .message.assistant .message-content {
171
- background: #f8f9fa;
172
- color: #333;
 
 
 
173
  }
174
 
175
  .message-time {
@@ -181,30 +181,34 @@
181
 
182
  /* 思考过程块样式 */
183
  .think-block {
184
- margin-bottom: 8px;
185
- width: 100%;
186
- background: #f8f9fa;
187
- border: 1px solid #eee;
188
- border-radius: 8px;
189
- padding: 8px 12px;
 
 
190
  }
191
 
192
  .think-header {
193
- font-size: 12px;
194
- color: #666;
 
 
195
  cursor: pointer;
196
- padding: 4px 0;
197
  display: flex;
 
198
  align-items: center;
199
- gap: 4px;
200
  }
201
 
202
  .think-content {
203
- font-size: 12px;
204
- color: #666;
205
- padding: 8px 0;
206
  white-space: pre-wrap;
207
- word-break: break-word;
 
208
  }
209
 
210
  .message-time {
@@ -388,154 +392,400 @@ button[type="submit"]:disabled {
388
  /* 重置一些基础样式 */
389
  .app-container {
390
  display: flex;
 
391
  height: 100vh;
392
- width: 100vw;
393
  overflow: hidden;
394
  }
395
 
396
- .sidebar {
397
- width: var(--sidebar-width);
398
- border-right: 1px solid var(--border-color);
399
- height: 100vh;
400
- background: #ffffff;
401
- position: relative;
402
  display: flex;
403
- flex-direction: column;
 
 
 
 
 
404
  }
405
 
406
- .main-content {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
  flex: 1;
408
- height: 100vh;
409
  overflow: hidden;
 
 
 
 
 
 
410
  display: flex;
411
  flex-direction: column;
412
- background: #ffffff;
413
- position: relative; /* 添加相对定位 */
414
  }
415
 
416
- /* 统一按钮样式 */
417
- button {
418
- background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-hover) 100%);
419
- color: white;
420
- padding: 8px 16px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  border: none;
422
- border-radius: 6px;
423
  cursor: pointer;
424
- font-size: 0.875rem;
425
- font-weight: 500;
426
- transition: all 0.2s ease;
 
 
427
  }
428
 
429
- button:hover {
430
- background: linear-gradient(135deg, var(--primary-hover) 0%, #1d4ed8 100%);
431
- transform: translateY(-1px);
432
- box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2);
433
  }
434
 
435
- /* ChatList 样式优化 */
436
  .chat-list {
437
  flex: 1;
438
- padding: 15px;
439
- display: flex;
440
- flex-direction: column;
441
- gap: 10px;
442
  overflow-y: auto;
443
- padding-bottom: 200px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  }
445
 
446
  .chat-item {
447
  display: flex;
448
  justify-content: space-between;
449
  align-items: center;
450
- padding: 8px 12px;
451
- border-radius: 6px;
452
  cursor: pointer;
453
- transition: background-color 0.2s;
 
454
  }
455
 
456
  .chat-item:hover {
457
- background-color: #f5f5f5;
458
  }
459
 
460
  .chat-item.active {
461
- background-color: #e3f2fd;
462
  }
463
 
464
- /* Settings 样式调整 */
465
- .settings-wrapper {
466
- position: absolute;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  left: 0;
 
468
  bottom: 0;
469
- width: 100%;
470
- background: #ffffff;
471
- border-top: 1px solid var(--border-color);
472
- padding: 15px;
 
473
  }
474
 
475
- .settings-container {
476
- background: #ffffff;
477
  border-radius: 8px;
 
 
 
 
 
 
 
478
  }
479
 
480
- .setting-item {
481
- margin-bottom: 12px;
 
 
 
 
 
 
 
482
  }
483
 
484
- .setting-item:last-child {
485
- margin-bottom: 0;
486
  }
487
 
488
- .setting-item label {
489
- display: block;
490
- margin-bottom: 4px;
491
- font-weight: 500;
492
- color: #333;
493
- font-size: 12px;
494
  }
495
 
496
- .setting-item input {
497
- width: 100%;
498
- padding: 6px 8px;
499
- border: 1px solid #ddd;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
  border-radius: 4px;
501
- font-size: 12px;
 
 
 
 
502
  }
503
 
504
- .setting-item input:focus {
505
  outline: none;
506
- border-color: #007bff;
507
- box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
508
  }
509
 
510
- button[type="submit"] {
511
- background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
512
  color: white;
513
- padding: 8px 16px;
514
  border: none;
515
- border-radius: 6px;
 
 
516
  cursor: pointer;
517
- font-size: 0.875rem;
518
- font-weight: 500;
519
- width: 100%;
520
- margin-top: 8px;
521
- transition: all 0.2s ease;
522
  }
523
 
524
- button[type="submit"]:hover {
525
- background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
526
- transform: translateY(-1px);
527
- box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2);
528
  }
529
 
530
- button[type="submit"]:disabled {
531
- background: #e2e8f0;
532
  cursor: not-allowed;
533
- transform: none;
534
- box-shadow: none;
535
  }
536
 
537
- .assistant .message-content .think-block {
538
- margin: 0 0 8px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
  }
540
 
541
  /* 状态提示样式 */
 
150
 
151
  .message-content {
152
  padding: 12px 16px;
153
+ max-width: 70%;
154
+ word-wrap: break-word;
 
 
 
155
  }
156
 
157
  .content-text {
 
165
  }
166
 
167
  .message.assistant .message-content {
168
+ align-self: flex-start;
169
+ background-color: #f1f3f5;
170
+ color: #212529;
171
+ border-radius: 18px 18px 18px 0;
172
+ position: relative;
173
  }
174
 
175
  .message-time {
 
181
 
182
  /* 思考过程块样式 */
183
  .think-block {
184
+ margin-bottom: 10px;
185
+ border: 1px solid #dee2e6;
186
+ border-radius: 4px;
187
+ overflow: hidden;
188
+ width: 90%;
189
+ background-color: #f8f9fa;
190
+ margin-left: auto;
191
+ margin-right: auto;
192
  }
193
 
194
  .think-header {
195
+ background-color: #e9ecef;
196
+ padding: 8px 12px;
197
+ font-size: 0.875rem;
198
+ font-weight: 600;
199
  cursor: pointer;
 
200
  display: flex;
201
+ justify-content: space-between;
202
  align-items: center;
 
203
  }
204
 
205
  .think-content {
206
+ padding: 12px;
207
+ background-color: #f8f9fa;
208
+ font-size: 0.875rem;
209
  white-space: pre-wrap;
210
+ max-height: 300px;
211
+ overflow-y: auto;
212
  }
213
 
214
  .message-time {
 
392
  /* 重置一些基础样式 */
393
  .app-container {
394
  display: flex;
395
+ flex-direction: column;
396
  height: 100vh;
397
+ width: 100%;
398
  overflow: hidden;
399
  }
400
 
401
+ .app-header {
 
 
 
 
 
402
  display: flex;
403
+ justify-content: space-between;
404
+ align-items: center;
405
+ padding: 10px 20px;
406
+ background-color: #f8f9fa;
407
+ border-bottom: 1px solid #e9ecef;
408
+ height: 60px;
409
  }
410
 
411
+ .app-title {
412
+ font-size: 1.5rem;
413
+ font-weight: 600;
414
+ color: #333;
415
+ margin: 0;
416
+ }
417
+
418
+ .settings-button {
419
+ background-color: #f8f9fa;
420
+ border: 1px solid #dee2e6;
421
+ border-radius: 4px;
422
+ padding: 8px 16px;
423
+ font-size: 0.875rem;
424
+ cursor: pointer;
425
+ transition: all 0.2s ease;
426
+ }
427
+
428
+ .settings-button:hover {
429
+ background-color: #e9ecef;
430
+ }
431
+
432
+ .app-content {
433
+ display: flex;
434
  flex: 1;
 
435
  overflow: hidden;
436
+ }
437
+
438
+ /* Sidebar */
439
+ .sidebar {
440
+ width: 280px;
441
+ border-right: 1px solid #e9ecef;
442
  display: flex;
443
  flex-direction: column;
444
+ transition: width 0.3s ease;
 
445
  }
446
 
447
+ .sidebar.collapsed {
448
+ width: 50px;
449
+ overflow: hidden;
450
+ }
451
+
452
+ .sidebar.collapsed .chat-list,
453
+ .sidebar.collapsed .sidebar-header h2 {
454
+ display: none;
455
+ }
456
+
457
+ .sidebar-header {
458
+ display: flex;
459
+ justify-content: space-between;
460
+ align-items: center;
461
+ padding: 15px;
462
+ border-bottom: 1px solid #e9ecef;
463
+ }
464
+
465
+ .sidebar.collapsed .sidebar-header {
466
+ padding: 15px 5px;
467
+ justify-content: center;
468
+ }
469
+
470
+ .sidebar-header h2 {
471
+ font-size: 1rem;
472
+ font-weight: 600;
473
+ margin: 0;
474
+ }
475
+
476
+ .toggle-sidebar-button {
477
+ background: none;
478
  border: none;
479
+ font-size: 1.2rem;
480
  cursor: pointer;
481
+ padding: 5px;
482
+ display: flex;
483
+ align-items: center;
484
+ justify-content: center;
485
+ z-index: 10;
486
  }
487
 
488
+ .toggle-sidebar-button:hover {
489
+ background-color: #f1f3f5;
490
+ border-radius: 4px;
 
491
  }
492
 
493
+ /* Chat List */
494
  .chat-list {
495
  flex: 1;
 
 
 
 
496
  overflow-y: auto;
497
+ padding: 15px;
498
+ }
499
+
500
+ .new-chat {
501
+ width: 100%;
502
+ padding: 10px;
503
+ background-color: #4263eb;
504
+ color: white;
505
+ border: none;
506
+ border-radius: 4px;
507
+ cursor: pointer;
508
+ font-size: 0.875rem;
509
+ margin-bottom: 15px;
510
+ transition: background-color 0.2s ease;
511
+ }
512
+
513
+ .new-chat:hover {
514
+ background-color: #3b5bdb;
515
  }
516
 
517
  .chat-item {
518
  display: flex;
519
  justify-content: space-between;
520
  align-items: center;
521
+ padding: 10px;
522
+ border-radius: 4px;
523
  cursor: pointer;
524
+ margin-bottom: 5px;
525
+ transition: background-color 0.2s ease;
526
  }
527
 
528
  .chat-item:hover {
529
+ background-color: #f1f3f5;
530
  }
531
 
532
  .chat-item.active {
533
+ background-color: #e7f5ff;
534
  }
535
 
536
+ .delete-btn {
537
+ opacity: 0;
538
+ background-color: #ffe3e3;
539
+ color: #e03131;
540
+ border: none;
541
+ border-radius: 4px;
542
+ padding: 4px 8px;
543
+ font-size: 0.75rem;
544
+ cursor: pointer;
545
+ transition: opacity 0.2s ease, background-color 0.2s ease;
546
+ }
547
+
548
+ .chat-item:hover .delete-btn {
549
+ opacity: 1;
550
+ }
551
+
552
+ .delete-btn:hover {
553
+ background-color: #ffc9c9;
554
+ }
555
+
556
+ .empty-state {
557
+ color: #868e96;
558
+ text-align: center;
559
+ padding: 20px;
560
+ font-size: 0.875rem;
561
+ }
562
+
563
+ /* Main Content */
564
+ .main-content {
565
+ flex: 1;
566
+ display: flex;
567
+ flex-direction: column;
568
+ overflow: hidden;
569
+ }
570
+
571
+ /* Welcome Screen */
572
+ .welcome-screen {
573
+ display: flex;
574
+ flex-direction: column;
575
+ align-items: center;
576
+ justify-content: center;
577
+ height: 100%;
578
+ padding: 20px;
579
+ text-align: center;
580
+ }
581
+
582
+ .welcome-screen h2 {
583
+ font-size: 1.5rem;
584
+ font-weight: 600;
585
+ margin-bottom: 10px;
586
+ }
587
+
588
+ .welcome-screen p {
589
+ color: #495057;
590
+ margin-bottom: 20px;
591
+ }
592
+
593
+ .new-chat-button {
594
+ background-color: #4263eb;
595
+ color: white;
596
+ border: none;
597
+ border-radius: 4px;
598
+ padding: 10px 20px;
599
+ font-size: 1rem;
600
+ cursor: pointer;
601
+ transition: background-color 0.2s ease;
602
+ }
603
+
604
+ .new-chat-button:hover {
605
+ background-color: #3b5bdb;
606
+ }
607
+
608
+ /* Settings Modal */
609
+ .settings-overlay {
610
+ position: fixed;
611
+ top: 0;
612
  left: 0;
613
+ right: 0;
614
  bottom: 0;
615
+ background-color: rgba(0, 0, 0, 0.5);
616
+ display: flex;
617
+ align-items: center;
618
+ justify-content: center;
619
+ z-index: 1000;
620
  }
621
 
622
+ .settings-modal {
623
+ background-color: white;
624
  border-radius: 8px;
625
+ width: 500px;
626
+ max-width: 90%;
627
+ max-height: 90vh;
628
+ overflow-y: auto;
629
+ position: relative;
630
+ padding: 20px;
631
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
632
  }
633
 
634
+ .close-settings-button {
635
+ position: absolute;
636
+ top: 10px;
637
+ right: 10px;
638
+ background: none;
639
+ border: none;
640
+ font-size: 1.5rem;
641
+ cursor: pointer;
642
+ color: #868e96;
643
  }
644
 
645
+ .close-settings-button:hover {
646
+ color: #495057;
647
  }
648
 
649
+ /* Chat Window */
650
+ .chat-window {
651
+ display: flex;
652
+ flex-direction: column;
653
+ height: 100%;
654
+ overflow: hidden;
655
  }
656
 
657
+ .chat-messages {
658
+ flex: 1;
659
+ overflow-y: auto;
660
+ padding: 20px;
661
+ }
662
+
663
+ .message {
664
+ margin-bottom: 20px;
665
+ display: flex;
666
+ flex-direction: column;
667
+ }
668
+
669
+ .message.user .message-content {
670
+ align-self: flex-end;
671
+ background-color: #4263eb;
672
+ color: white;
673
+ border-radius: 18px 18px 0 18px;
674
+ max-width: 85%;
675
+ }
676
+
677
+ .message.assistant .message-content {
678
+ align-self: flex-start;
679
+ background-color: #f1f3f5;
680
+ color: #212529;
681
+ border-radius: 18px 18px 18px 0;
682
+ }
683
+
684
+ .message-content {
685
+ padding: 12px 16px;
686
+ max-width: 70%;
687
+ word-wrap: break-word;
688
+ }
689
+
690
+ .message-time {
691
+ font-size: 0.75rem;
692
+ color: #868e96;
693
+ margin-top: 5px;
694
+ align-self: flex-end;
695
+ }
696
+
697
+ .message.user .message-time {
698
+ align-self: flex-end;
699
+ }
700
+
701
+ .message.assistant .message-time {
702
+ align-self: flex-start;
703
+ }
704
+
705
+ .chat-input {
706
+ display: flex;
707
+ padding: 15px;
708
+ border-top: 1px solid #e9ecef;
709
+ }
710
+
711
+ .message-input {
712
+ flex: 1;
713
+ padding: 12px;
714
+ border: 1px solid #dee2e6;
715
  border-radius: 4px;
716
+ font-size: 1rem;
717
+ resize: none;
718
+ min-height: 50px;
719
+ max-height: 150px;
720
+ margin-right: 10px;
721
  }
722
 
723
+ .message-input:focus {
724
  outline: none;
725
+ border-color: #4263eb;
 
726
  }
727
 
728
+ .chat-input button {
729
+ background-color: #4263eb;
730
  color: white;
 
731
  border: none;
732
+ border-radius: 4px;
733
+ padding: 0 20px;
734
+ font-size: 1rem;
735
  cursor: pointer;
736
+ transition: background-color 0.2s ease;
 
 
 
 
737
  }
738
 
739
+ .chat-input button:hover {
740
+ background-color: #3b5bdb;
 
 
741
  }
742
 
743
+ .chat-input button:disabled {
744
+ background-color: #adb5bd;
745
  cursor: not-allowed;
 
 
746
  }
747
 
748
+ /* Error and Loading */
749
+ .error-message {
750
+ position: fixed;
751
+ bottom: 20px;
752
+ left: 50%;
753
+ transform: translateX(-50%);
754
+ background-color: #ffe3e3;
755
+ color: #e03131;
756
+ padding: 10px 20px;
757
+ border-radius: 4px;
758
+ font-size: 0.875rem;
759
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
760
+ z-index: 1000;
761
+ }
762
+
763
+ .loading {
764
+ position: fixed;
765
+ bottom: 20px;
766
+ left: 50%;
767
+ transform: translateX(-50%);
768
+ background-color: #e7f5ff;
769
+ color: #1971c2;
770
+ padding: 10px 20px;
771
+ border-radius: 4px;
772
+ font-size: 0.875rem;
773
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
774
+ z-index: 1000;
775
+ }
776
+
777
+ .loading-cursor {
778
+ display: inline-block;
779
+ width: 10px;
780
+ height: 20px;
781
+ background-color: #212529;
782
+ animation: blink 1s infinite;
783
+ margin-left: 5px;
784
+ }
785
+
786
+ @keyframes blink {
787
+ 0%, 100% { opacity: 1; }
788
+ 50% { opacity: 0; }
789
  }
790
 
791
  /* 状态提示样式 */