mikao007 commited on
Commit
c5edfec
·
verified ·
1 Parent(s): 17abbb1

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +388 -779
index.html CHANGED
@@ -3,10 +3,8 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>LLM+ Web scraping Application</title>
7
  <style>
8
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
9
-
10
  * {
11
  margin: 0;
12
  padding: 0;
@@ -14,644 +12,288 @@
14
  }
15
 
16
  body {
17
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
18
- background: radial-gradient(ellipse at top, #667eea 0%, #764ba2 50%, #f093fb 100%);
19
- min-height: 100vh;
20
- position: relative;
21
- overflow-x: hidden;
22
  }
23
 
24
- body::before {
25
- content: '';
26
  position: fixed;
27
  top: 0;
28
  left: 0;
29
  width: 100%;
30
  height: 100%;
31
- background:
32
- radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
33
- radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%),
34
- radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.2) 0%, transparent 50%);
35
- z-index: -1;
 
36
  }
37
 
38
- .container {
39
- max-width: 1600px;
40
- margin: 0 auto;
41
- padding: 15px;
42
- min-height: 100vh;
43
  }
44
 
45
- .header {
 
 
 
 
 
46
  text-align: center;
47
- margin-bottom: 25px;
48
- color: white;
49
- position: relative;
50
- }
51
-
52
- .main-title {
53
- font-size: 3.2rem;
54
- font-weight: 700;
55
- margin-bottom: 15px;
56
- text-shadow: 0 4px 8px rgba(0,0,0,0.3);
57
- background: linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%);
58
- background-clip: text;
59
- -webkit-background-clip: text;
60
- -webkit-text-fill-color: transparent;
61
- letter-spacing: -0.5px;
62
  }
63
 
64
- .subtitle {
65
- font-size: 1.2rem;
66
- opacity: 0.95;
67
- font-weight: 400;
68
- text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
69
- margin-bottom: 5px;
70
  }
71
 
72
- .app-container {
73
- display: flex;
74
- background: rgba(255,255,255,0.95);
75
- backdrop-filter: blur(20px);
76
- border-radius: 20px;
77
- box-shadow:
78
- 0 25px 50px rgba(0,0,0,0.15),
79
- 0 0 0 1px rgba(255,255,255,0.2);
80
- overflow: hidden;
81
- min-height: 800px;
82
- border: 1px solid rgba(255,255,255,0.2);
83
- }
84
-
85
- .sidebar {
86
- width: 320px;
87
- background: linear-gradient(180deg,
88
- rgba(30, 41, 59, 0.95) 0%,
89
- rgba(51, 65, 85, 0.95) 50%,
90
- rgba(30, 41, 59, 0.95) 100%);
91
- backdrop-filter: blur(10px);
92
- padding: 0;
93
- display: flex;
94
- flex-direction: column;
95
- position: relative;
96
  }
97
 
98
- .sidebar::before {
99
- content: '';
100
- position: absolute;
101
- top: 0;
102
- left: 0;
103
- right: 0;
104
- bottom: 0;
105
- background: linear-gradient(45deg,
106
- rgba(59, 130, 246, 0.1) 0%,
107
- rgba(147, 51, 234, 0.1) 100%);
108
- pointer-events: none;
109
  }
110
 
111
- .tab-button {
112
- padding: 30px 35px;
113
- border: none;
114
- background: transparent;
115
- color: #f1f5f9;
116
- font-size: 1.15rem;
117
- font-weight: 500;
118
- cursor: pointer;
119
- text-align: left;
120
- transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
121
- border-bottom: 1px solid rgba(255,255,255,0.08);
122
- position: relative;
123
- overflow: hidden;
124
  }
125
 
126
- .tab-button::before {
127
- content: '';
128
- position: absolute;
129
- top: 0;
130
- left: -100%;
131
  width: 100%;
132
- height: 100%;
133
- background: linear-gradient(90deg,
134
- transparent 0%,
135
- rgba(59, 130, 246, 0.2) 50%,
136
- transparent 100%);
137
- transition: left 0.6s ease;
 
 
138
  }
139
 
140
- .tab-button:hover::before {
141
- left: 100%;
 
142
  }
143
 
144
- .tab-button:hover {
145
- background: rgba(59, 130, 246, 0.15);
146
- transform: translateX(8px);
147
- color: #ffffff;
148
  }
149
 
150
- .tab-button.active {
151
- background: linear-gradient(135deg,
152
- rgba(59, 130, 246, 0.3) 0%,
153
- rgba(147, 51, 234, 0.3) 100%);
154
- border-left: 4px solid #3b82f6;
155
- color: #ffffff;
156
- box-shadow: inset 0 0 20px rgba(59, 130, 246, 0.2);
157
- }
158
-
159
- .tab-button.active::after {
160
- content: '';
161
- position: absolute;
162
- right: 0;
163
- top: 50%;
164
- transform: translateY(-50%);
165
- width: 0;
166
- height: 0;
167
- border-top: 12px solid transparent;
168
- border-bottom: 12px solid transparent;
169
- border-right: 12px solid rgba(255,255,255,0.95);
170
- filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1));
171
- }
172
-
173
- .tab-title {
174
- font-weight: 600;
175
- margin-bottom: 8px;
176
- font-size: 1.1rem;
177
  display: flex;
178
  align-items: center;
 
 
179
  }
180
 
181
- .tab-title::before {
182
- content: '⚡';
183
- margin-right: 10px;
184
- font-size: 1.2rem;
185
- }
186
-
187
- .tab-button:nth-child(2) .tab-title::before {
188
- content: '🤖';
189
- }
190
-
191
- .tab-button:nth-child(3) .tab-title::before {
192
- content: '📸';
193
- }
194
-
195
- .tab-description {
196
- font-size: 0.95rem;
197
- opacity: 0.85;
198
- line-height: 1.5;
199
- color: #cbd5e1;
200
- }
201
-
202
- .content {
203
  flex: 1;
204
- padding: 0;
205
- background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
206
- position: relative;
207
- }
208
-
209
- .tab-content {
210
- display: none;
211
- width: 100%;
212
- height: 100%;
213
- padding: 25px;
214
- }
215
-
216
- .tab-content.active {
217
- display: block;
218
- }
219
-
220
- .iframe-container {
221
- width: 100%;
222
- height: 750px;
223
- border-radius: 15px;
224
- overflow: hidden;
225
- box-shadow:
226
- 0 20px 40px rgba(0,0,0,0.12),
227
- 0 0 0 1px rgba(0,0,0,0.05);
228
- background: white;
229
- position: relative;
230
- transition: transform 0.3s ease, box-shadow 0.3s ease;
231
  }
232
 
233
- .iframe-container:hover {
234
- transform: translateY(-2px);
235
- box-shadow:
236
- 0 25px 50px rgba(0,0,0,0.15),
237
- 0 0 0 1px rgba(0,0,0,0.05);
238
  }
239
 
240
- iframe {
241
- width: 100%;
242
- height: 100%;
243
  border: none;
244
- border-radius: 15px;
245
- }
246
-
247
- .loading {
248
- display: flex;
249
- justify-content: center;
250
- align-items: center;
251
- height: 100%;
252
- color: #64748b;
253
- font-size: 1.15rem;
254
- font-weight: 500;
255
- background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
256
- }
257
-
258
- .loading::before {
259
- content: '';
260
- width: 24px;
261
- height: 24px;
262
- border: 3px solid #e2e8f0;
263
- border-top: 3px solid #3b82f6;
264
- border-radius: 50%;
265
- animation: spin 1s linear infinite;
266
- margin-right: 15px;
267
  }
268
 
269
- @keyframes spin {
270
- 0% { transform: rotate(0deg); }
271
- 100% { transform: rotate(360deg); }
272
  }
273
 
274
- .floating-elements {
275
- position: fixed;
276
- top: 0;
277
- left: 0;
278
  width: 100%;
279
- height: 100%;
280
- pointer-events: none;
281
- z-index: -1;
282
- }
283
-
284
- .floating-element {
285
- position: absolute;
286
- background: rgba(255,255,255,0.1);
287
- border-radius: 50%;
288
- animation: float 6s ease-in-out infinite;
289
- }
290
-
291
- .floating-element:nth-child(1) {
292
- top: 20%;
293
- left: 10%;
294
- width: 60px;
295
- height: 60px;
296
- animation-delay: 0s;
297
- }
298
-
299
- .floating-element:nth-child(2) {
300
- top: 60%;
301
- right: 15%;
302
- width: 80px;
303
- height: 80px;
304
- animation-delay: 2s;
305
- }
306
-
307
- .floating-element:nth-child(3) {
308
- bottom: 30%;
309
- left: 20%;
310
- width: 40px;
311
- height: 40px;
312
- animation-delay: 4s;
313
  }
314
 
315
- @keyframes float {
316
- 0%, 100% { transform: translateY(0px) rotate(0deg); }
317
- 33% { transform: translateY(-20px) rotate(120deg); }
318
- 66% { transform: translateY(10px) rotate(240deg); }
319
  }
320
 
321
- @media (max-width: 1024px) {
322
- .container {
323
- padding: 10px;
324
- }
325
-
326
- .app-container {
327
- min-height: 700px;
328
- }
329
-
330
- .sidebar {
331
- width: 280px;
332
- }
333
-
334
- .iframe-container {
335
- height: 650px;
336
- }
337
  }
338
 
339
- @media (max-width: 768px) {
340
- .app-container {
341
- flex-direction: column;
342
- min-height: auto;
343
- }
344
-
345
- .sidebar {
346
- width: 100%;
347
- flex-direction: row;
348
- overflow-x: auto;
349
- min-height: auto;
350
- }
351
-
352
- .tab-button {
353
- min-width: 250px;
354
- white-space: nowrap;
355
- padding: 20px 25px;
356
- }
357
-
358
- .tab-button.active::after {
359
- display: none;
360
- }
361
-
362
- .iframe-container {
363
- height: 500px;
364
- }
365
-
366
- .main-title {
367
- font-size: 2.5rem;
368
- }
369
-
370
- .tab-content {
371
- padding: 15px;
372
- }
373
  }
374
 
375
- @media (max-width: 480px) {
376
- .main-title {
377
- font-size: 2rem;
378
- }
379
-
380
- .iframe-container {
381
- height: 400px;
382
- }
383
  }
384
 
385
- /* 登入頁面樣式 */
386
- .login-container {
387
- position: fixed;
388
- top: 0;
389
- left: 0;
390
- width: 100%;
391
- height: 100%;
392
- background: radial-gradient(ellipse at center, #667eea 0%, #764ba2 50%, #f093fb 100%);
393
  display: flex;
394
- justify-content: center;
395
  align-items: center;
396
- z-index: 1000;
397
- transition: opacity 0.5s ease, visibility 0.5s ease;
398
- }
399
-
400
- .login-container.hidden {
401
- opacity: 0;
402
- visibility: hidden;
403
- }
404
-
405
- .login-box {
406
- background: rgba(255, 255, 255, 0.95);
407
- backdrop-filter: blur(20px);
408
- border-radius: 20px;
409
- padding: 40px;
410
- box-shadow:
411
- 0 25px 50px rgba(0,0,0,0.2),
412
- 0 0 0 1px rgba(255,255,255,0.3);
413
- width: 100%;
414
- max-width: 420px;
415
- position: relative;
416
- overflow: hidden;
417
- }
418
-
419
- .login-box::before {
420
- content: '';
421
- position: absolute;
422
- top: 0;
423
- left: 0;
424
- right: 0;
425
- height: 4px;
426
- background: linear-gradient(90deg, #3b82f6, #8b5cf6, #ec4899);
427
  }
428
 
429
- .login-header {
430
- text-align: center;
431
- margin-bottom: 35px;
432
  }
433
 
434
- .login-title {
435
- font-size: 2.2rem;
436
- font-weight: 700;
437
- margin-bottom: 10px;
438
- background: linear-gradient(135deg, #1e293b 0%, #3b82f6 100%);
439
- background-clip: text;
440
- -webkit-background-clip: text;
441
- -webkit-text-fill-color: transparent;
442
  }
443
 
444
- .login-subtitle {
445
- color: #64748b;
446
- font-size: 1rem;
447
- font-weight: 400;
448
  }
449
 
450
- .form-group {
451
- margin-bottom: 25px;
452
- position: relative;
453
  }
454
 
455
- .form-label {
456
- display: block;
457
- margin-bottom: 8px;
458
- color: #374151;
459
- font-weight: 500;
460
- font-size: 0.95rem;
461
  }
462
 
463
- .form-input {
464
  width: 100%;
465
  padding: 15px 20px;
466
- border: 2px solid #e5e7eb;
467
- border-radius: 12px;
468
- font-size: 1rem;
469
- transition: all 0.3s ease;
470
- background: rgba(255, 255, 255, 0.8);
471
- box-sizing: border-box;
472
- }
473
-
474
- .form-input:focus {
475
- outline: none;
476
- border-color: #3b82f6;
477
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
478
- background: rgba(255, 255, 255, 1);
479
  }
480
 
481
- .captcha-container {
482
- display: flex;
483
- gap: 10px;
484
- align-items: center;
485
  }
486
 
487
- .captcha-display {
488
- background: #f8fafc;
489
- border: 2px solid #e5e7eb;
490
- border-radius: 8px;
491
- padding: 12px 15px;
492
- font-family: 'Courier New', monospace;
493
- font-size: 1.2rem;
494
- font-weight: bold;
495
- color: #374151;
496
- letter-spacing: 3px;
497
- text-align: center;
498
- user-select: none;
499
- min-width: 100px;
500
- position: relative;
501
- overflow: hidden;
502
  }
503
 
504
- .captcha-display::before {
505
- content: '';
506
- position: absolute;
507
- top: 0;
508
- left: 0;
509
- right: 0;
510
- bottom: 0;
511
- background: repeating-linear-gradient(
512
- 45deg,
513
- transparent,
514
- transparent 2px,
515
- rgba(59, 130, 246, 0.1) 2px,
516
- rgba(59, 130, 246, 0.1) 4px
517
- );
518
- }
519
-
520
- .captcha-refresh {
521
- background: #3b82f6;
522
- color: white;
523
- border: none;
524
- border-radius: 8px;
525
- padding: 12px 15px;
526
- cursor: pointer;
527
- font-size: 1.1rem;
528
- transition: all 0.3s ease;
529
- display: flex;
530
- align-items: center;
531
- justify-content: center;
532
  }
533
 
534
- .captcha-refresh:hover {
535
- background: #2563eb;
536
- transform: translateY(-1px);
537
  }
538
 
539
- .captcha-input {
540
- flex: 1;
541
  }
542
 
543
- .login-button {
544
  width: 100%;
545
- background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
546
- color: white;
547
  border: none;
548
- border-radius: 12px;
549
- padding: 16px;
550
- font-size: 1.1rem;
551
- font-weight: 600;
552
- cursor: pointer;
553
- transition: all 0.3s ease;
554
- position: relative;
555
- overflow: hidden;
556
  }
557
 
558
- .login-button::before {
559
- content: '';
560
- position: absolute;
561
- top: 0;
562
- left: -100%;
563
- width: 100%;
564
- height: 100%;
565
- background: linear-gradient(90deg,
566
- transparent 0%,
567
- rgba(255, 255, 255, 0.2) 50%,
568
- transparent 100%);
569
- transition: left 0.6s ease;
570
  }
571
 
572
- .login-button:hover::before {
573
- left: 100%;
 
574
  }
575
 
576
- .login-button:hover {
577
- transform: translateY(-2px);
578
- box-shadow: 0 8px 25px rgba(59, 130, 246, 0.3);
579
  }
580
 
581
- .login-button:active {
582
- transform: translateY(0);
 
 
 
583
  }
584
 
585
- .error-message {
586
- background: #fef2f2;
587
- border: 1px solid #fecaca;
588
- color: #dc2626;
589
- padding: 12px 15px;
590
- border-radius: 8px;
591
- margin-top: 15px;
592
- font-size: 0.9rem;
593
- text-align: center;
594
- display: none;
595
  }
596
 
597
- .success-message {
598
- background: #f0fdf4;
599
- border: 1px solid #bbf7d0;
600
- color: #16a34a;
601
- padding: 12px 15px;
602
- border-radius: 8px;
603
- margin-top: 15px;
604
- font-size: 0.9rem;
605
- text-align: center;
606
- display: none;
607
  }
608
 
609
- /* 登出按鈕 */
610
- .logout-button {
611
- position: fixed;
612
- top: 20px;
613
- right: 20px;
614
- background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
615
- color: white;
616
  border: none;
617
- border-radius: 12px;
618
- padding: 12px 20px;
619
- font-size: 0.95rem;
620
- font-weight: 600;
621
- cursor: pointer;
622
- transition: all 0.3s ease;
623
- box-shadow: 0 4px 15px rgba(239, 68, 68, 0.3);
624
- z-index: 100;
625
- }
626
-
627
- .logout-button:hover {
628
- transform: translateY(-2px);
629
- box-shadow: 0 6px 20px rgba(239, 68, 68, 0.4);
630
- }
631
-
632
- .logout-button:active {
633
- transform: translateY(0);
634
- }
635
-
636
- /* 響應式設計 */
637
- @media (max-width: 480px) {
638
- .login-box {
639
- margin: 20px;
640
- padding: 30px 25px;
641
- }
642
-
643
- .login-title {
644
- font-size: 1.8rem;
645
- }
646
-
647
- .captcha-container {
648
- flex-direction: column;
649
- gap: 15px;
650
- }
651
-
652
- .captcha-display {
653
- width: 100%;
654
- }
655
  }
656
  </style>
657
  </head>
@@ -659,99 +301,153 @@
659
  <!-- 登入頁面 -->
660
  <div class="login-container" id="loginContainer">
661
  <div class="login-box">
662
- <div class="login-header">
663
- <h1 class="login-title">系統登入</h1>
664
- <p class="login-subtitle">歡迎使用 LLM+ Web scraping Application</p>
 
 
 
 
 
 
 
665
  </div>
 
 
 
 
 
 
 
 
666
 
667
- <form id="loginForm" onsubmit="handleLogin(event)">
668
- <div class="form-group">
669
- <label class="form-label" for="username">帳號</label>
670
- <input type="text" id="username" class="form-input" placeholder="請輸入帳號" required>
671
- </div>
672
-
673
- <div class="form-group">
674
- <label class="form-label" for="password">密碼</label>
675
- <input type="password" id="password" class="form-input" placeholder="請輸入密碼" required>
676
- </div>
677
-
678
- <div class="form-group">
679
- <label class="form-label" for="captcha">驗證碼</label>
680
- <div class="captcha-container">
681
- <div class="captcha-display" id="captchaDisplay"></div>
682
- <button type="button" class="captcha-refresh" onclick="generateCaptcha()" title="重新生成驗證碼">
683
- 🔄
684
- </button>
685
- <input type="text" id="captcha" class="form-input captcha-input" placeholder="請輸入驗證碼" required>
686
- </div>
687
- </div>
688
-
689
- <button type="submit" class="login-button">登入</button>
690
-
691
- <div class="error-message" id="errorMessage"></div>
692
- <div class="success-message" id="successMessage"></div>
693
- </form>
694
  </div>
695
  </div>
696
 
697
- <!-- 登出按鈕 -->
698
- <button class="logout-button" id="logoutButton" onclick="handleLogout()" style="display: none;">
699
- 登出
700
- </button>
701
-
702
- <div class="floating-elements">
703
- <div class="floating-element"></div>
704
- <div class="floating-element"></div>
705
- <div class="floating-element"></div>
706
- </div>
707
-
708
- <div class="container" id="mainContainer" style="display: none;">
709
  <div class="header">
710
- <h1 class="main-title">LLM+ Web scraping Application</h1>
711
- <p class="subtitle">mikao07@2025copyright</p>
712
  </div>
713
 
714
- <div class="app-container">
715
  <div class="sidebar">
716
- <button class="tab-button active" onclick="showTab('tab1')">
717
- <div class="tab-title">ESG爬蟲</div>
718
- <div class="tab-description">環境、社會與治理數據爬蟲工具</div>
719
- </button>
720
- <button class="tab-button" onclick="showTab('tab2')">
721
- <div class="tab-title">多模態API應用</div>
722
- <div class="tab-description">整合多種模態的API應用介面</div>
723
- </button>
724
- <button class="tab-button" onclick="showTab('tab3')">
725
- <div class="tab-title">OCR識別並傳送至LINE</div>
726
- <div class="tab-description">攝影機拍照OCR文字辨識並發送至LINE Bot</div>
727
- </button>
728
  </div>
729
 
730
- <div class="content">
731
- <div id="tab1" class="tab-content active">
732
- <div class="iframe-container">
733
- <div class="loading">載入中...</div>
734
- <iframe src="https://mikao007-g-space-st.hf.space" onload="hideLoading(this)"></iframe>
 
 
 
 
 
 
 
 
 
 
 
735
  </div>
736
  </div>
737
 
738
- <div id="tab2" class="tab-content">
739
- <div class="iframe-container">
740
- <div class="loading">載入中...</div>
741
- <iframe src="https://mikao007-groq-api-gradio.hf.space" onload="hideLoading(this)"></iframe>
 
 
 
 
 
 
 
 
742
  </div>
743
  </div>
744
 
745
- <div id="tab3" class="tab-content">
746
- <div class="iframe-container">
747
- <div class="loading">載入中...</div>
748
- <iframe
749
- src="https://mikao007-webcam-groq-linebot.hf.space"
750
- onload="hideLoading(this)"
751
- allow="camera *; microphone *; fullscreen *; clipboard-read; clipboard-write; web-share"
752
- sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-modals allow-downloads allow-top-navigation-by-user-activation"
753
- referrerpolicy="strict-origin-when-cross-origin">
754
- </iframe>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
  </div>
756
  </div>
757
  </div>
@@ -759,200 +455,113 @@
759
  </div>
760
 
761
  <script>
762
- // 全局變量
763
- let currentCaptcha = '';
764
- // 使用SHA-256
765
- const VALID_USERNAME_HASH = '8b3404dd5f3ff5c6a8c8fbd8b4a2c39c7bdf67fe31c1a46c1b63a2ed59e6d7b8';
766
- const VALID_PASSWORD_HASH = '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92';
767
-
768
- // SHA-256 雜湊函數
769
- async function sha256(text) {
770
- const encoder = new TextEncoder();
771
- const data = encoder.encode(text);
772
- const hash = await crypto.subtle.digest('SHA-256', data);
773
- const hashArray = Array.from(new Uint8Array(hash));
774
- const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
775
- return hashHex;
776
- }
777
-
778
  // 生成驗證碼
779
  function generateCaptcha() {
780
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
781
  let result = '';
782
- for (let i = 0; i < 5; i++) {
783
  result += chars.charAt(Math.floor(Math.random() * chars.length));
784
  }
785
- currentCaptcha = result;
786
- document.getElementById('captchaDisplay').textContent = result;
787
- }
788
-
789
- // 顯示錯誤訊息
790
- function showError(message) {
791
- const errorDiv = document.getElementById('errorMessage');
792
- const successDiv = document.getElementById('successMessage');
793
- errorDiv.textContent = message;
794
- errorDiv.style.display = 'block';
795
- successDiv.style.display = 'none';
796
-
797
- // 3秒後自動隱藏
798
- setTimeout(() => {
799
- errorDiv.style.display = 'none';
800
- }, 3000);
801
  }
802
 
803
- // 顯示功訊息
804
- function showSuccess(message) {
805
- const successDiv = document.getElementById('successMessage');
806
- const errorDiv = document.getElementById('errorMessage');
807
- successDiv.textContent = message;
808
- successDiv.style.display = 'block';
809
- errorDiv.style.display = 'none';
810
- }
811
 
812
- // 處理登入 (使用雜湊驗證)
813
- async function handleLogin(event) {
814
- event.preventDefault();
815
-
816
- const username = document.getElementById('username').value.trim();
817
  const password = document.getElementById('password').value;
818
- const captcha = document.getElementById('captcha').value.trim().toUpperCase();
819
-
820
- // 驗證輸入
821
- if (!username || !password || !captcha) {
822
- showError('請填寫所有欄位');
823
- return;
824
- }
825
 
826
  // 驗證驗證碼
827
- if (captcha !== currentCaptcha) {
828
- showError('驗證碼錯誤,請重新輸入');
829
- generateCaptcha(); // 重新生成驗證碼
830
- document.getElementById('captcha').value = '';
831
  return;
832
  }
833
 
834
  try {
835
- // 計算輸入的帳號密碼雜湊值
836
  const usernameHash = await sha256(username);
837
  const passwordHash = await sha256(password);
838
-
839
- // 驗證帳號密碼雜湊 (使用動態計算的正確雜湊值)
840
- if (usernameHash !== window.CORRECT_USERNAME_HASH || passwordHash !== window.CORRECT_PASSWORD_HASH) {
841
- showError('帳號或密碼錯誤');
842
- generateCaptcha(); // 重新生成驗證碼
843
- document.getElementById('captcha').value = '';
844
- return;
845
- }
846
-
847
- // 登入成功
848
- showSuccess('登入成功,正在跳轉...');
849
 
850
- setTimeout(() => {
851
- // 隱藏登入頁面
852
- document.getElementById('loginContainer').classList.add('hidden');
 
 
 
 
853
 
854
- // 顯示主系統
855
  setTimeout(() => {
856
- document.getElementById('loginContainer').style.display = 'none';
857
- document.getElementById('mainContainer').style.display = 'block';
858
- document.getElementById('logoutButton').style.display = 'block';
859
- }, 500);
860
- }, 1000);
 
 
 
861
  } catch (error) {
862
- showError('系統錯誤,請稍後再試');
863
- console.error('雜湊計算錯誤:', error);
864
- }
865
- }
866
-
867
- // 處理登出
868
- function handleLogout() {
869
- if (confirm('確定要登出嗎?')) {
870
- // 隱藏主系統
871
- document.getElementById('mainContainer').style.display = 'none';
872
- document.getElementById('logoutButton').style.display = 'none';
873
-
874
- // 顯示登入頁面
875
- document.getElementById('loginContainer').style.display = 'flex';
876
- document.getElementById('loginContainer').classList.remove('hidden');
877
-
878
- // 清空表單
879
- document.getElementById('loginForm').reset();
880
  generateCaptcha();
881
-
882
- // 隱藏訊息
883
- document.getElementById('errorMessage').style.display = 'none';
884
- document.getElementById('successMessage').style.display = 'none';
885
  }
886
  }
887
 
888
- // 標籤切換功能
889
- function showTab(tabId) {
890
- // 隱藏所有內容
891
- const contents = document.querySelectorAll('.tab-content');
892
- contents.forEach(content => {
893
- content.classList.remove('active');
894
- });
895
-
896
- // 移除所有按鈕的active狀態
897
- const buttons = document.querySelectorAll('.tab-button');
898
- buttons.forEach(button => {
899
- button.classList.remove('active');
900
- });
901
-
902
- // 顯示選中的內容
903
- document.getElementById(tabId).classList.add('active');
904
-
905
- // 添加選中按鈕的active狀態
906
- event.target.closest('.tab-button').classList.add('active');
907
  }
908
 
909
- function hideLoading(iframe) {
910
- const container = iframe.parentElement;
911
- const loading = container.querySelector('.loading');
912
- if (loading) {
913
- loading.style.display = 'none';
914
- }
915
- iframe.style.display = 'block';
 
 
 
 
 
 
916
  }
917
 
918
- // 計算並顯示正確的雜湊值 (僅供開發驗證使用)
919
- async function calculateCorrectHashes() {
920
- const usernameHash = await sha256('ROOT2025');
921
- const passwordHash = await sha256('123456');
922
- console.log('正確的帳號雜湊值:', usernameHash);
923
- console.log('正確的密碼雜湊值:', passwordHash);
 
 
 
 
 
 
924
 
925
- // 更新正確的雜湊值
926
- window.CORRECT_USERNAME_HASH = usernameHash;
927
- window.CORRECT_PASSWORD_HASH = passwordHash;
928
  }
929
 
930
- // 初始化
931
- document.addEventListener('DOMContentLoaded', async function() {
932
- // 初始化載入動畫
933
- const iframes = document.querySelectorAll('iframe');
934
- iframes.forEach(iframe => {
935
- iframe.style.display = 'none';
936
- });
937
-
938
- // 計算正確的雜湊值
939
- await calculateCorrectHashes();
940
-
941
- // 生成第一個驗證碼
942
- generateCaptcha();
943
-
944
- // 為驗證碼輸入框添加大寫轉換
945
- document.getElementById('captcha').addEventListener('input', function(e) {
946
- e.target.value = e.target.value.toUpperCase();
947
- });
948
-
949
- // Enter 鍵提交登入表單
950
- document.getElementById('loginForm').addEventListener('keypress', async function(e) {
951
- if (e.key === 'Enter') {
952
- await handleLogin(e);
953
- }
954
- });
955
  });
956
  </script>
957
  </body>
958
- </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>PKM_RAG 系統</title>
7
  <style>
 
 
8
  * {
9
  margin: 0;
10
  padding: 0;
 
12
  }
13
 
14
  body {
15
+ font-family: 'Poppins', sans-serif;
16
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
+ height: 100vh;
18
+ overflow: hidden;
 
19
  }
20
 
21
+ /* 登入頁面樣式 */
22
+ .login-container {
23
  position: fixed;
24
  top: 0;
25
  left: 0;
26
  width: 100%;
27
  height: 100%;
28
+ background: url("https://images.unsplash.com/photo-1503264116251-35a269479413") no-repeat center center/cover;
29
+ display: flex;
30
+ justify-content: center;
31
+ align-items: center;
32
+ z-index: 1000;
33
+ transition: opacity 0.5s ease;
34
  }
35
 
36
+ .login-container.hidden {
37
+ opacity: 0;
38
+ pointer-events: none;
 
 
39
  }
40
 
41
+ .login-box {
42
+ background: rgba(255, 255, 255, 0.1);
43
+ backdrop-filter: blur(15px);
44
+ border-radius: 20px;
45
+ padding: 40px;
46
+ width: 400px;
47
  text-align: center;
48
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
49
+ animation: fadeIn 1.5s ease;
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
 
52
+ @keyframes fadeIn {
53
+ from {opacity: 0; transform: translateY(-50px);}
54
+ to {opacity: 1; transform: translateY(0);}
 
 
 
55
  }
56
 
57
+ .login-box h2 {
58
+ color: white;
59
+ margin-bottom: 30px;
60
+ font-size: 28px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
 
63
+ .input-group {
64
+ margin-bottom: 20px;
65
+ text-align: left;
 
 
 
 
 
 
 
 
66
  }
67
 
68
+ .input-group label {
69
+ color: white;
70
+ font-weight: bold;
71
+ display: block;
72
+ margin-bottom: 8px;
 
 
 
 
 
 
 
 
73
  }
74
 
75
+ .input-group input {
 
 
 
 
76
  width: 100%;
77
+ padding: 12px;
78
+ border: none;
79
+ border-radius: 10px;
80
+ background: rgba(255, 255, 255, 0.2);
81
+ color: white;
82
+ font-size: 16px;
83
+ outline: none;
84
+ transition: 0.3s;
85
  }
86
 
87
+ .input-group input:focus {
88
+ background: rgba(255, 255, 255, 0.3);
89
+ box-shadow: 0 0 10px #00f2fe;
90
  }
91
 
92
+ .input-group input::placeholder {
93
+ color: rgba(255, 255, 255, 0.7);
 
 
94
  }
95
 
96
+ .captcha-container {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  display: flex;
98
  align-items: center;
99
+ gap: 10px;
100
+ margin-bottom: 20px;
101
  }
102
 
103
+ .captcha-code {
104
+ background: rgba(255, 255, 255, 0.2);
105
+ color: white;
106
+ padding: 10px 15px;
107
+ border-radius: 8px;
108
+ font-weight: bold;
109
+ font-size: 18px;
110
+ letter-spacing: 3px;
111
+ user-select: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  flex: 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  }
114
 
115
+ .captcha-input {
116
+ flex: 1;
 
 
 
117
  }
118
 
119
+ .refresh-captcha {
120
+ background: rgba(255, 255, 255, 0.2);
 
121
  border: none;
122
+ color: white;
123
+ padding: 10px;
124
+ border-radius: 8px;
125
+ cursor: pointer;
126
+ transition: 0.3s;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  }
128
 
129
+ .refresh-captcha:hover {
130
+ background: rgba(255, 255, 255, 0.3);
 
131
  }
132
 
133
+ .login-btn {
 
 
 
134
  width: 100%;
135
+ padding: 12px;
136
+ border: none;
137
+ border-radius: 10px;
138
+ background: linear-gradient(135deg, #4facfe, #00f2fe);
139
+ color: white;
140
+ font-size: 18px;
141
+ font-weight: bold;
142
+ cursor: pointer;
143
+ transition: 0.3s;
144
+ margin-bottom: 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  }
146
 
147
+ .login-btn:hover {
148
+ transform: scale(1.05);
149
+ background: linear-gradient(135deg, #00f2fe, #4facfe);
 
150
  }
151
 
152
+ .message {
153
+ margin-top: 15px;
154
+ font-size: 14px;
155
+ font-weight: bold;
156
+ min-height: 20px;
 
 
 
 
 
 
 
 
 
 
 
157
  }
158
 
159
+ /* 主系統樣式 */
160
+ .main-system {
161
+ display: none;
162
+ height: 100vh;
163
+ background: #f5f5f5;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  }
165
 
166
+ .main-system.active {
167
+ display: block;
 
 
 
 
 
 
168
  }
169
 
170
+ .header {
171
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
172
+ color: white;
173
+ padding: 15px 30px;
 
 
 
 
174
  display: flex;
175
+ justify-content: space-between;
176
  align-items: center;
177
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  }
179
 
180
+ .header h1 {
181
+ font-size: 24px;
 
182
  }
183
 
184
+ .logout-btn {
185
+ background: rgba(255, 255, 255, 0.2);
186
+ border: none;
187
+ color: white;
188
+ padding: 10px 20px;
189
+ border-radius: 8px;
190
+ cursor: pointer;
191
+ transition: 0.3s;
192
  }
193
 
194
+ .logout-btn:hover {
195
+ background: rgba(255, 255, 255, 0.3);
 
 
196
  }
197
 
198
+ .content-container {
199
+ display: flex;
200
+ height: calc(100vh - 70px);
201
  }
202
 
203
+ .sidebar {
204
+ width: 250px;
205
+ background: white;
206
+ box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1);
207
+ padding: 20px 0;
 
208
  }
209
 
210
+ .tab-button {
211
  width: 100%;
212
  padding: 15px 20px;
213
+ border: none;
214
+ background: none;
215
+ text-align: left;
216
+ cursor: pointer;
217
+ transition: 0.3s;
218
+ font-size: 16px;
219
+ color: #666;
220
+ border-left: 4px solid transparent;
 
 
 
 
 
221
  }
222
 
223
+ .tab-button:hover {
224
+ background: #f0f0f0;
225
+ color: #333;
 
226
  }
227
 
228
+ .tab-button.active {
229
+ background: #e3f2fd;
230
+ color: #1976d2;
231
+ border-left-color: #1976d2;
 
 
 
 
 
 
 
 
 
 
 
232
  }
233
 
234
+ .main-content {
235
+ flex: 1;
236
+ padding: 10px;
237
+ overflow-y: auto;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  }
239
 
240
+ .tab-content {
241
+ display: none;
 
242
  }
243
 
244
+ .tab-content.active {
245
+ display: block;
246
  }
247
 
248
+ .iframe-container {
249
  width: 100%;
250
+ height: calc(100vh - 120px);
 
251
  border: none;
252
+ border-radius: 10px;
253
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
254
  }
255
 
256
+ .welcome-message {
257
+ text-align: center;
258
+ padding: 50px;
259
+ color: #666;
 
 
 
 
 
 
 
 
260
  }
261
 
262
+ .welcome-message h2 {
263
+ margin-bottom: 20px;
264
+ color: #333;
265
  }
266
 
267
+ .welcome-message p {
268
+ font-size: 16px;
269
+ line-height: 1.6;
270
  }
271
 
272
+ .iframe-grid {
273
+ display: grid;
274
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
275
+ gap: 20px;
276
+ margin-top: 20px;
277
  }
278
 
279
+ .iframe-item {
280
+ background: white;
281
+ border-radius: 10px;
282
+ padding: 10px;
283
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
284
+ height: calc(100vh - 150px);
 
 
 
 
285
  }
286
 
287
+ .iframe-item h3 {
288
+ margin-bottom: 10px;
289
+ color: #333;
 
 
 
 
 
 
 
290
  }
291
 
292
+ .iframe-item iframe {
293
+ width: 100%;
294
+ height: calc(100vh - 180px);
 
 
 
 
295
  border: none;
296
+ border-radius: 8px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  }
298
  </style>
299
  </head>
 
301
  <!-- 登入頁面 -->
302
  <div class="login-container" id="loginContainer">
303
  <div class="login-box">
304
+ <h2>PKM_RAG 系統登入</h2>
305
+
306
+ <div class="input-group">
307
+ <label for="username">使用者名稱</label>
308
+ <input type="text" id="username" placeholder="請輸入使用者名稱">
309
+ </div>
310
+
311
+ <div class="input-group">
312
+ <label for="password">密碼</label>
313
+ <input type="password" id="password" placeholder="請輸入密碼">
314
  </div>
315
+
316
+ <div class="captcha-container">
317
+ <div class="captcha-code" id="captchaCode"></div>
318
+ <input type="text" class="captcha-input" id="captchaInput" placeholder="驗證碼">
319
+ <button class="refresh-captcha" onclick="generateCaptcha()">🔄</button>
320
+ </div>
321
+
322
+ <button class="login-btn" onclick="login()">登入系統</button>
323
 
324
+ <div class="message" id="message"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  </div>
326
  </div>
327
 
328
+ <!-- 主系統 -->
329
+ <div class="main-system" id="mainSystem">
 
 
 
 
 
 
 
 
 
 
330
  <div class="header">
331
+ <h1>PKM_RAG 知識管理系統</h1>
332
+ <button class="logout-btn" onclick="logout()">回到登入頁面</button>
333
  </div>
334
 
335
+ <div class="content-container">
336
  <div class="sidebar">
337
+ <button class="tab-button active" onclick="showTab('welcome')">🏠 系統首頁</button>
338
+ <button class="tab-button" onclick="showTab('chatbot')">🤖 PDF 聊天機器人</button>
339
+ <button class="tab-button" onclick="showTab('longchain')">🔗 LongChain Resend</button>
340
+ <button class="tab-button" onclick="showTab('groq')">⚡ Groq API</button>
341
+ <button class="tab-button" onclick="showTab('webcam')">📹 Webcam Groq</button>
342
+ <button class="tab-button" onclick="showTab('analysis')">📊 圖分析</button>
343
+ <button class="tab-button" onclick="showTab('twilio')">📱 Twilio 訊息</button>
344
+ <button class="tab-button" onclick="showTab('settings')">⚙️ 系統設定</button>
345
+ <button class="tab-button" onclick="showTab('help')">❓ 使用說明</button>
 
 
 
346
  </div>
347
 
348
+ <div class="main-content">
349
+ <div class="tab-content active" id="welcome">
350
+ <div class="welcome-message">
351
+ <h2>歡迎使用 PKM_RAG 系統</h2>
352
+ <p>這是一個整合的知識管理和問答系統��提供以下功能:</p>
353
+ <br>
354
+ <p>📄 <strong>PDF 文件處理</strong> - 上傳並分析 PDF 文件內容</p>
355
+ <p>💬 <strong>智能問答</strong> - 基於文件內容進行問答對話</p>
356
+ <p>📧 <strong>郵件分享</strong> - 將問答記錄發送郵件</p>
357
+ <p>🔗 <strong>LongChain 整合</strong> - 鏈式處理和 Resend 郵件服務</p>
358
+ <p>⚡ <strong>Groq API</strong> - 高速 AI 推理服務</p>
359
+ <p>📹 <strong>Webcam 功能</strong> - 即時影像處理</p>
360
+ <p>📊 <strong>多圖分析</strong> - 批量圖像分析處理</p>
361
+ <p>📱 <strong>Twilio 訊息</strong> - 簡訊發送服務</p>
362
+ <br>
363
+ <p>請點擊左側選單開始使用各項功能。</p>
364
  </div>
365
  </div>
366
 
367
+ <div class="tab-content" id="chatbot">
368
+ <iframe
369
+ src="http://127.0.0.1:7860"
370
+ class="iframe-container"
371
+ frameborder="0">
372
+ </iframe>
373
+ </div>
374
+
375
+ <div class="tab-content" id="longchain">
376
+ <div class="iframe-item">
377
+ <h3>LongChain Resend 服務</h3>
378
+ <iframe src="https://mikao007-longchain-resend.hf.space" frameborder="0"></iframe>
379
  </div>
380
  </div>
381
 
382
+ <div class="tab-content" id="groq">
383
+ <div class="iframe-item">
384
+ <h3>Groq API Gradio 服務</h3>
385
+ <iframe src="https://mikao007-groq-api-gradio.hf.space" frameborder="0"></iframe>
386
+ </div>
387
+ </div>
388
+
389
+ <div class="tab-content" id="webcam">
390
+ <div class="iframe-item">
391
+ <h3>Webcam Groq LineBot 服務</h3>
392
+ <iframe src="https://mikao007-webcam-groq-linebot.hf.space" frameborder="0"></iframe>
393
+ </div>
394
+ </div>
395
+
396
+ <div class="tab-content" id="analysis">
397
+ <div class="iframe-item">
398
+ <h3>多圖分析服務</h3>
399
+ <iframe src="https://mikao007-anliz-muti-pic.hf.space" frameborder="0"></iframe>
400
+ </div>
401
+ </div>
402
+
403
+ <div class="tab-content" id="twilio">
404
+ <div class="iframe-item">
405
+ <h3>Twilio 訊息發送服務</h3>
406
+ <iframe src="https://mikao007-twilio-messagesend.hf.space" frameborder="0"></iframe>
407
+ </div>
408
+ </div>
409
+
410
+ <div class="tab-content" id="settings">
411
+ <div class="welcome-message">
412
+ <h2>系統設定</h2>
413
+ <p>這裡可以進行系統相關的設定調整。</p>
414
+ <br>
415
+ <p>🔧 <strong>API 設定</strong> - 配置 Google Gemini 和 Resend API</p>
416
+ <p>📁 <strong>文件管理</strong> - 管理已上傳的文件</p>
417
+ <p>🎨 <strong>界面設定</strong> - 自訂系統外觀</p>
418
+ <p>🔒 <strong>安全設定</strong> - 修改登入密碼</p>
419
+ <br>
420
+ <h3>📋 系統資訊</h3>
421
+ <p>• 系統版本:PKM_RAG v1.0</p>
422
+ <p>• 支援格式:PDF, DOCX, TXT</p>
423
+ <p>• AI 模型:Gemini 2.0 Flash</p>
424
+ <p>• 郵件服務:Resend</p>
425
+ </div>
426
+ </div>
427
+
428
+ <div class="tab-content" id="help">
429
+ <div class="welcome-message">
430
+ <h2>使用說明</h2>
431
+ <p>PKM_RAG 系統使用指南:</p>
432
+ <br>
433
+ <h3>📋 基本操作流程</h3>
434
+ <p>1. 點擊「PDF 聊天機器人」進入主要功能</p>
435
+ <p>2. 上傳您的 PDF 文件進行處理</p>
436
+ <p>3. 開始與文件內容進行問答對話</p>
437
+ <p>4. 可將問答記錄下載或發送郵件</p>
438
+ <br>
439
+ <h3>🔗 整合服務</h3>
440
+ <p>• <strong>LongChain Resend</strong> - 鏈式處理和郵件服務</p>
441
+ <p>• <strong>Groq API</strong> - 高速 AI 推理</p>
442
+ <p>• <strong>Webcam Groq</strong> - 即時影像處理</p>
443
+ <p>• <strong>多圖分析</strong> - 批量圖像分析</p>
444
+ <p>• <strong>Twilio 訊息</strong> - 簡訊發送</p>
445
+ <br>
446
+ <h3>💡 使用技巧</h3>
447
+ <p>• 支援多個 PDF 文件同時處理</p>
448
+ <p>• 問答支援中文和英文</p>
449
+ <p>• 可下載 DOCX 格式的問答記錄</p>
450
+ <p>• 郵件發送支援 HTML 格式</p>
451
  </div>
452
  </div>
453
  </div>
 
455
  </div>
456
 
457
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
  // 生成驗證碼
459
  function generateCaptcha() {
460
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
461
  let result = '';
462
+ for (let i = 0; i < 6; i++) {
463
  result += chars.charAt(Math.floor(Math.random() * chars.length));
464
  }
465
+ document.getElementById('captchaCode').textContent = result;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
  }
467
 
468
+ // 頁面載入時生驗證碼
469
+ window.onload = function() {
470
+ generateCaptcha();
471
+ };
 
 
 
 
472
 
473
+ // 登入功能
474
+ async function login() {
475
+ const username = document.getElementById('username').value;
 
 
476
  const password = document.getElementById('password').value;
477
+ const captchaInput = document.getElementById('captchaInput').value;
478
+ const captchaCode = document.getElementById('captchaCode').textContent;
479
+ const message = document.getElementById('message');
 
 
 
 
480
 
481
  // 驗證驗證碼
482
+ if (captchaInput.toUpperCase() !== captchaCode) {
483
+ message.style.color = 'red';
484
+ message.textContent = '❌ 驗證碼錯誤!';
485
+ generateCaptcha();
486
  return;
487
  }
488
 
489
  try {
490
+ // 使用 HASH 驗證帳號密碼
491
  const usernameHash = await sha256(username);
492
  const passwordHash = await sha256(password);
 
 
 
 
 
 
 
 
 
 
 
493
 
494
+ // 預設帳號密碼的 HASH 值
495
+ const correctUsernameHash = 'd7113846e19051e6d5752f60dcb53329e9563b2c7655452fb9aea5f27969cc4f'; // "ROOT2025" 的 SHA-256
496
+ const correctPasswordHash = '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92'; // "123456" 的 SHA-256
497
+
498
+ if (usernameHash === correctUsernameHash && passwordHash === correctPasswordHash) {
499
+ message.style.color = 'lightgreen';
500
+ message.textContent = '✅ 登入成功!正在進入系統...';
501
 
 
502
  setTimeout(() => {
503
+ document.getElementById('loginContainer').classList.add('hidden');
504
+ document.getElementById('mainSystem').classList.add('active');
505
+ }, 1000);
506
+ } else {
507
+ message.style.color = 'red';
508
+ message.textContent = '❌ 使用者名稱或密碼錯誤!';
509
+ generateCaptcha();
510
+ }
511
  } catch (error) {
512
+ message.style.color = 'red';
513
+ message.textContent = '❌ 登入驗證時發生錯誤';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  generateCaptcha();
 
 
 
 
515
  }
516
  }
517
 
518
+ // SHA-256 雜湊函數
519
+ async function sha256(message) {
520
+ const msgBuffer = new TextEncoder().encode(message);
521
+ const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
522
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
523
+ const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
524
+ return hashHex;
 
 
 
 
 
 
 
 
 
 
 
 
525
  }
526
 
527
+ // 登出功能
528
+ function logout() {
529
+ document.getElementById('mainSystem').classList.remove('active');
530
+ document.getElementById('loginContainer').classList.remove('hidden');
531
+
532
+ // 清空輸入欄位
533
+ document.getElementById('username').value = '';
534
+ document.getElementById('password').value = '';
535
+ document.getElementById('captchaInput').value = '';
536
+ document.getElementById('message').textContent = '';
537
+
538
+ // 重新生成驗證碼
539
+ generateCaptcha();
540
  }
541
 
542
+ // 頁籤切換功能
543
+ function showTab(tabName) {
544
+ // 隱藏所有頁籤內容
545
+ const tabContents = document.querySelectorAll('.tab-content');
546
+ tabContents.forEach(content => content.classList.remove('active'));
547
+
548
+ // 移除所有按鈕的 active 狀態
549
+ const tabButtons = document.querySelectorAll('.tab-button');
550
+ tabButtons.forEach(button => button.classList.remove('active'));
551
+
552
+ // 顯示選中的頁籤內容
553
+ document.getElementById(tabName).classList.add('active');
554
 
555
+ // 設定對應按鈕為 active
556
+ event.target.classList.add('active');
 
557
  }
558
 
559
+ // Enter 鍵登入
560
+ document.addEventListener('keypress', function(e) {
561
+ if (e.key === 'Enter') {
562
+ login();
563
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
564
  });
565
  </script>
566
  </body>
567
+ </html>