i0110 commited on
Commit
1934692
·
verified ·
1 Parent(s): 198475b

Update public/index.html

Browse files
Files changed (1) hide show
  1. public/index.html +131 -29
public/index.html CHANGED
@@ -331,7 +331,7 @@
331
  margin-top: 10px;
332
  font-size: 14px;
333
  }
334
- .logout-button {
335
  background: var(--action-button-bg);
336
  border: none;
337
  color: var(--text-color);
@@ -340,9 +340,8 @@
340
  cursor: pointer;
341
  font-size: 13px;
342
  transition: background 0.2s ease;
343
- margin-left: auto;
344
  }
345
- .logout-button:hover {
346
  background: var(--action-button-hover);
347
  }
348
  .header-container {
@@ -351,6 +350,10 @@
351
  align-items: center;
352
  margin-bottom: 20px;
353
  }
 
 
 
 
354
  </style>
355
  </head>
356
  <body>
@@ -358,7 +361,10 @@
358
  <div class="overview">
359
  <div class="header-container">
360
  <div class="overview-title">📊 系统概览</div>
361
- <button class="logout-button" id="logoutButton" style="display: none;" onclick="logout()">登出</button>
 
 
 
362
  </div>
363
  <div class="theme-toggle">
364
  主题:
@@ -439,44 +445,104 @@
439
 
440
  // 登录状态管理
441
  function checkLoginStatus() {
442
- const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true';
443
- document.getElementById('loginOverlay').style.display = isLoggedIn ? 'none' : 'flex';
444
- document.getElementById('logoutButton').style.display = isLoggedIn ? 'block' : 'none';
445
- if (isLoggedIn) {
446
- updateActionButtons(true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  } else {
 
 
448
  updateActionButtons(false);
449
  }
450
  }
451
 
 
 
 
 
 
 
 
 
 
 
 
452
  function login() {
453
  const username = document.getElementById('username').value;
454
  const password = document.getElementById('password').value;
455
  const loginError = document.getElementById('loginError');
456
 
457
- // 模拟后端验证 (前端硬编码验证,实际环境中应通过接口验证)
458
- fetch('/api/config').then(response => response.json()).then(config => {
459
- // 这里仅做演示,实际环境中不应将用户凭据硬编码在前端
460
- const adminUsername = 'admin'; // 默认值,实际应从环境变量获取,但这里无法直接获取后端环境变量
461
- const adminPassword = 'password'; // 默认值,实际应从环境变量获取
462
- if (username === adminUsername && password === adminPassword) {
463
- localStorage.setItem('isLoggedIn', 'true');
464
- loginError.style.display = 'none';
 
 
 
 
465
  checkLoginStatus();
466
  } else {
467
- loginError.textContent = '用户名或密码错误';
468
  loginError.style.display = 'block';
469
  }
470
- }).catch(err => {
471
- loginError.textContent = '登录系统错误,请��后重试';
 
 
472
  loginError.style.display = 'block';
473
- console.error('获取配置失败,无法验证登录:', err);
474
  });
475
  }
476
 
477
  function logout() {
478
- localStorage.removeItem('isLoggedIn');
479
- checkLoginStatus();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
  }
481
 
482
  function updateActionButtons(isLoggedIn) {
@@ -712,14 +778,32 @@
712
 
713
  async function restartSpace(repoId) {
714
  try {
 
 
 
 
 
 
715
  const encodedRepoId = encodeURIComponent(repoId);
716
- const response = await fetch(`/api/proxy/restart/${encodedRepoId}`, { method: 'POST' });
 
 
 
 
 
717
  const result = await response.json();
718
  if (result.success) {
719
  alert(`重启成功: ${repoId}`);
720
  } else {
721
- alert(`重启失败: ${result.error || '未知错误'}`);
722
- console.error(`重启失败 (${repoId}):`, result.error, result.details);
 
 
 
 
 
 
 
723
  }
724
  } catch (error) {
725
  console.error(`重启失败 (${repoId}):`, error);
@@ -729,14 +813,32 @@
729
 
730
  async function rebuildSpace(repoId) {
731
  try {
 
 
 
 
 
 
732
  const encodedRepoId = encodeURIComponent(repoId);
733
- const response = await fetch(`/api/proxy/rebuild/${encodedRepoId}`, { method: 'POST' });
 
 
 
 
 
734
  const result = await response.json();
735
  if (result.success) {
736
  alert(`重建成功: ${repoId}`);
737
  } else {
738
- alert(`重建失败: ${result.error || '未知错误'}`);
739
- console.error(`重建失败 (${repoId}):`, result.error, result.details);
 
 
 
 
 
 
 
740
  }
741
  } catch (error) {
742
  console.error(`重建失败 (${repoId}):`, error);
 
331
  margin-top: 10px;
332
  font-size: 14px;
333
  }
334
+ .login-button, .logout-button {
335
  background: var(--action-button-bg);
336
  border: none;
337
  color: var(--text-color);
 
340
  cursor: pointer;
341
  font-size: 13px;
342
  transition: background 0.2s ease;
 
343
  }
344
+ .login-button:hover, .logout-button:hover {
345
  background: var(--action-button-hover);
346
  }
347
  .header-container {
 
350
  align-items: center;
351
  margin-bottom: 20px;
352
  }
353
+ .auth-buttons {
354
+ display: flex;
355
+ gap: 10px;
356
+ }
357
  </style>
358
  </head>
359
  <body>
 
361
  <div class="overview">
362
  <div class="header-container">
363
  <div class="overview-title">📊 系统概览</div>
364
+ <div class="auth-buttons">
365
+ <button class="login-button" id="loginButton" onclick="showLoginForm()">登录</button>
366
+ <button class="logout-button" id="logoutButton" style="display: none;" onclick="logout()">登出</button>
367
+ </div>
368
  </div>
369
  <div class="theme-toggle">
370
  主题:
 
445
 
446
  // 登录状态管理
447
  function checkLoginStatus() {
448
+ const token = localStorage.getItem('authToken');
449
+ if (token) {
450
+ fetch('/api/verify-token', {
451
+ method: 'POST',
452
+ headers: {
453
+ 'Content-Type': 'application/json',
454
+ },
455
+ body: JSON.stringify({ token })
456
+ })
457
+ .then(response => response.json())
458
+ .then(data => {
459
+ if (data.success) {
460
+ document.getElementById('loginButton').style.display = 'none';
461
+ document.getElementById('logoutButton').style.display = 'block';
462
+ updateActionButtons(true);
463
+ } else {
464
+ localStorage.removeItem('authToken');
465
+ document.getElementById('loginButton').style.display = 'block';
466
+ document.getElementById('logoutButton').style.display = 'none';
467
+ updateActionButtons(false);
468
+ }
469
+ })
470
+ .catch(error => {
471
+ console.error('验证 token 失败:', error);
472
+ localStorage.removeItem('authToken');
473
+ document.getElementById('loginButton').style.display = 'block';
474
+ document.getElementById('logoutButton').style.display = 'none';
475
+ updateActionButtons(false);
476
+ });
477
  } else {
478
+ document.getElementById('loginButton').style.display = 'block';
479
+ document.getElementById('logoutButton').style.display = 'none';
480
  updateActionButtons(false);
481
  }
482
  }
483
 
484
+ function showLoginForm() {
485
+ document.getElementById('loginOverlay').style.display = 'flex';
486
+ document.getElementById('username').value = '';
487
+ document.getElementById('password').value = '';
488
+ document.getElementById('loginError').style.display = 'none';
489
+ }
490
+
491
+ function hideLoginForm() {
492
+ document.getElementById('loginOverlay').style.display = 'none';
493
+ }
494
+
495
  function login() {
496
  const username = document.getElementById('username').value;
497
  const password = document.getElementById('password').value;
498
  const loginError = document.getElementById('loginError');
499
 
500
+ fetch('/api/login', {
501
+ method: 'POST',
502
+ headers: {
503
+ 'Content-Type': 'application/json',
504
+ },
505
+ body: JSON.stringify({ username, password })
506
+ })
507
+ .then(response => response.json())
508
+ .then(data => {
509
+ if (data.success) {
510
+ localStorage.setItem('authToken', data.token);
511
+ hideLoginForm();
512
  checkLoginStatus();
513
  } else {
514
+ loginError.textContent = data.message || '登录失败';
515
  loginError.style.display = 'block';
516
  }
517
+ })
518
+ .catch(error => {
519
+ console.error('登录请求失败:', error);
520
+ loginError.textContent = '登录请求失败,请稍后重试';
521
  loginError.style.display = 'block';
 
522
  });
523
  }
524
 
525
  function logout() {
526
+ const token = localStorage.getItem('authToken');
527
+ if (token) {
528
+ fetch('/api/logout', {
529
+ method: 'POST',
530
+ headers: {
531
+ 'Content-Type': 'application/json',
532
+ },
533
+ body: JSON.stringify({ token })
534
+ })
535
+ .then(response => response.json())
536
+ .then(data => {
537
+ localStorage.removeItem('authToken');
538
+ checkLoginStatus();
539
+ })
540
+ .catch(error => {
541
+ console.error('登出失败:', error);
542
+ localStorage.removeItem('authToken');
543
+ checkLoginStatus();
544
+ });
545
+ }
546
  }
547
 
548
  function updateActionButtons(isLoggedIn) {
 
778
 
779
  async function restartSpace(repoId) {
780
  try {
781
+ const token = localStorage.getItem('authToken');
782
+ if (!token) {
783
+ alert('请先登录以执行此操作');
784
+ showLoginForm();
785
+ return;
786
+ }
787
  const encodedRepoId = encodeURIComponent(repoId);
788
+ const response = await fetch(`/api/proxy/restart/${encodedRepoId}`, {
789
+ method: 'POST',
790
+ headers: {
791
+ 'Authorization': `Bearer ${token}`
792
+ }
793
+ });
794
  const result = await response.json();
795
  if (result.success) {
796
  alert(`重启成功: ${repoId}`);
797
  } else {
798
+ if (response.status === 401) {
799
+ alert('登录已过期,请重新登录');
800
+ localStorage.removeItem('authToken');
801
+ checkLoginStatus();
802
+ showLoginForm();
803
+ } else {
804
+ alert(`重启失败: ${result.error || '未知错误'}`);
805
+ console.error(`重启失败 (${repoId}):`, result.error, result.details);
806
+ }
807
  }
808
  } catch (error) {
809
  console.error(`重启失败 (${repoId}):`, error);
 
813
 
814
  async function rebuildSpace(repoId) {
815
  try {
816
+ const token = localStorage.getItem('authToken');
817
+ if (!token) {
818
+ alert('请先登录以执行此操作');
819
+ showLoginForm();
820
+ return;
821
+ }
822
  const encodedRepoId = encodeURIComponent(repoId);
823
+ const response = await fetch(`/api/proxy/rebuild/${encodedRepoId}`, {
824
+ method: 'POST',
825
+ headers: {
826
+ 'Authorization': `Bearer ${token}`
827
+ }
828
+ });
829
  const result = await response.json();
830
  if (result.success) {
831
  alert(`重建成功: ${repoId}`);
832
  } else {
833
+ if (response.status === 401) {
834
+ alert('登录已过期,请重新登录');
835
+ localStorage.removeItem('authToken');
836
+ checkLoginStatus();
837
+ showLoginForm();
838
+ } else {
839
+ alert(`重建失败: ${result.error || '未知错误'}`);
840
+ console.error(`重建失败 (${repoId}):`, result.error, result.details);
841
+ }
842
  }
843
  } catch (error) {
844
  console.error(`重建失败 (${repoId}):`, error);