i0110 commited on
Commit
1fab873
·
verified ·
1 Parent(s): 870d8d4

Update public/index.html

Browse files
Files changed (1) hide show
  1. public/index.html +95 -58
public/index.html CHANGED
@@ -386,10 +386,10 @@
386
  </button>
387
  </div>
388
  <div id="summary">
389
- <div>总用户数: <span id="totalUsers">0</span></div>
390
  <div>总实例数: <span id="totalServers">0</span></div>
391
  <div>在线实例: <span id="onlineServers">0</span></div>
392
  <div>离线实例: <span id="offlineServers">0</span></div>
 
393
  <div>总上传: <span id="totalUpload">0 B/s</span></div>
394
  <div>总下载: <span id="totalDownload">0 B/s</span></div>
395
  </div>
@@ -452,55 +452,66 @@
452
 
453
  initTheme();
454
 
 
 
 
455
  // 登录状态管理
456
  function checkLoginStatus() {
457
- return new Promise((resolve) => {
458
- const token = localStorage.getItem('authToken');
459
- const loginButton = document.getElementById('loginButton');
460
- const logoutButton = document.getElementById('logoutButton');
461
 
462
- // 初始化时先隐藏操作按钮,确保在验证完成前不显示
463
- updateActionButtons(false);
 
 
464
  loginButton.style.display = 'block';
465
  logoutButton.style.display = 'none';
 
466
 
467
- if (token) {
468
- fetch('/api/verify-token', {
469
- method: 'POST',
470
- headers: {
471
- 'Content-Type': 'application/json',
472
- },
473
- body: JSON.stringify({ token })
474
- })
475
- .then(response => response.json())
476
- .then(data => {
477
- if (data.success) {
478
- loginButton.style.display = 'none';
479
- logoutButton.style.display = 'block';
480
- updateActionButtons(true);
481
- } else {
482
- localStorage.removeItem('authToken');
483
- loginButton.style.display = 'block';
484
- logoutButton.style.display = 'none';
485
- updateActionButtons(false);
486
- }
487
- resolve(data.success);
488
- })
489
- .catch(error => {
490
- console.error('验证 token 失败:', error);
491
  localStorage.removeItem('authToken');
 
492
  loginButton.style.display = 'block';
493
  logoutButton.style.display = 'none';
494
  updateActionButtons(false);
495
- resolve(false);
496
- });
497
- } else {
 
 
 
 
498
  loginButton.style.display = 'block';
499
  logoutButton.style.display = 'none';
500
  updateActionButtons(false);
501
- resolve(false);
502
- }
503
- });
 
 
 
 
 
 
 
504
  }
505
 
506
  function showLoginForm() {
@@ -529,10 +540,16 @@
529
  .then(response => response.json())
530
  .then(data => {
531
  if (data.success) {
 
532
  localStorage.setItem('authToken', data.token);
 
533
  hideLoginForm();
534
- checkLoginStatus();
 
 
 
535
  } else {
 
536
  loginError.textContent = data.message || '登录失败';
537
  loginError.style.display = 'block';
538
  }
@@ -556,31 +573,49 @@
556
  })
557
  .then(response => response.json())
558
  .then(data => {
 
559
  localStorage.removeItem('authToken');
560
- checkLoginStatus();
 
 
 
561
  })
562
  .catch(error => {
563
- console.error('登出失败:', error);
564
  localStorage.removeItem('authToken');
565
- checkLoginStatus();
 
 
 
566
  });
 
 
 
 
 
 
567
  }
568
  }
569
 
570
- function updateActionButtons(isLoggedIn) {
 
 
571
  const cards = document.querySelectorAll('.server-card');
572
  cards.forEach(card => {
573
  const buttons = card.querySelector('.action-buttons');
574
  if (buttons) {
575
- buttons.style.display = isLoggedIn ? 'flex' : 'none';
576
  }
577
  });
578
  }
579
 
580
- // 页面加载时初始化登录状态
581
- document.addEventListener('DOMContentLoaded', async () => {
 
582
  await checkLoginStatus();
583
- });
 
 
584
 
585
  // 二次确认弹窗逻辑
586
  let pendingAction = null;
@@ -694,14 +729,10 @@
694
  }
695
  });
696
  updateSummary();
 
 
697
  }
698
 
699
- // 在页面完全加载并验证登录状态后初始化数据
700
- document.addEventListener('DOMContentLoaded', async () => {
701
- await checkLoginStatus();
702
- initialize();
703
- });
704
-
705
  function renderInstanceCard(instance) {
706
  const instanceId = instance.repo_id;
707
  instanceMap.set(instanceId, instance);
@@ -763,9 +794,9 @@
763
  <div class="metric-value download">N/A</div>
764
  </div>
765
  </div>
766
- <div class="action-buttons" style="display: none;">
767
  <button class="action-button" onclick="showConfirmDialog('restart', '${instance.repo_id}', '确认重启', '您确定要重启实例 ${instance.name} (${instance.repo_id}) 吗?')">重启</button>
768
- <button class="action-button" onclick="showConfirmDialog('rebuild', '${instance.repo_id}', '确认重建', '您确定要重建实例 ${instance.name} (${instance.repo_id}) 吗?')">重建</button>
769
  </div>
770
  `;
771
  userServers.appendChild(card);
@@ -835,7 +866,7 @@
835
  async function restartSpace(repoId) {
836
  try {
837
  const token = localStorage.getItem('authToken');
838
- if (!token) {
839
  alert('请先登录以执行此操作');
840
  showLoginForm();
841
  return;
@@ -854,7 +885,10 @@
854
  if (response.status === 401) {
855
  alert('登录已过期,请重新登录');
856
  localStorage.removeItem('authToken');
857
- checkLoginStatus();
 
 
 
858
  showLoginForm();
859
  } else {
860
  alert(`重启失败: ${result.error || '未知错误'}`);
@@ -870,7 +904,7 @@
870
  async function rebuildSpace(repoId) {
871
  try {
872
  const token = localStorage.getItem('authToken');
873
- if (!token) {
874
  alert('请先登录以执行此操作');
875
  showLoginForm();
876
  return;
@@ -889,7 +923,10 @@
889
  if (response.status === 401) {
890
  alert('登录已过期,请重新登录');
891
  localStorage.removeItem('authToken');
892
- checkLoginStatus();
 
 
 
893
  showLoginForm();
894
  } else {
895
  alert(`重建失败: ${result.error || '未知错误'}`);
 
386
  </button>
387
  </div>
388
  <div id="summary">
 
389
  <div>总实例数: <span id="totalServers">0</span></div>
390
  <div>在线实例: <span id="onlineServers">0</span></div>
391
  <div>离线实例: <span id="offlineServers">0</span></div>
392
+ <div>总用户数: <span id="totalUsers">0</span></div>
393
  <div>总上传: <span id="totalUpload">0 B/s</span></div>
394
  <div>总下载: <span id="totalDownload">0 B/s</span></div>
395
  </div>
 
452
 
453
  initTheme();
454
 
455
+ // 全局变量,表示当前是否已登录
456
+ let isLoggedIn = false;
457
+
458
  // 登录状态管理
459
  function checkLoginStatus() {
460
+ const token = localStorage.getItem('authToken');
461
+ const loginButton = document.getElementById('loginButton');
462
+ const logoutButton = document.getElementById('logoutButton');
 
463
 
464
+ // 先检查本地是否有 token,决定初始 UI 状态
465
+ if (token) {
466
+ console.log('本地存储中找到 token,尝试验证:', token.slice(0, 8) + '...');
467
+ // 先假设未登录,直到验证成功
468
  loginButton.style.display = 'block';
469
  logoutButton.style.display = 'none';
470
+ updateActionButtons(false);
471
 
472
+ // 发送请求验证 token
473
+ return fetch('/api/verify-token', {
474
+ method: 'POST',
475
+ headers: {
476
+ 'Content-Type': 'application/json',
477
+ },
478
+ body: JSON.stringify({ token })
479
+ })
480
+ .then(response => response.json())
481
+ .then(data => {
482
+ if (data.success) {
483
+ console.log('Token 验证成功,用户已登录');
484
+ isLoggedIn = true;
485
+ loginButton.style.display = 'none';
486
+ logoutButton.style.display = 'block';
487
+ updateActionButtons(true);
488
+ } else {
489
+ console.log('Token 验证失败,清除本地存储:', data.message);
 
 
 
 
 
 
490
  localStorage.removeItem('authToken');
491
+ isLoggedIn = false;
492
  loginButton.style.display = 'block';
493
  logoutButton.style.display = 'none';
494
  updateActionButtons(false);
495
+ }
496
+ return data.success;
497
+ })
498
+ .catch(error => {
499
+ console.error('验证 token 失败,清除本地存储:', error);
500
+ localStorage.removeItem('authToken');
501
+ isLoggedIn = false;
502
  loginButton.style.display = 'block';
503
  logoutButton.style.display = 'none';
504
  updateActionButtons(false);
505
+ return false;
506
+ });
507
+ } else {
508
+ console.log('本地存储中无 token,显示未登录状态');
509
+ isLoggedIn = false;
510
+ loginButton.style.display = 'block';
511
+ logoutButton.style.display = 'none';
512
+ updateActionButtons(false);
513
+ return Promise.resolve(false);
514
+ }
515
  }
516
 
517
  function showLoginForm() {
 
540
  .then(response => response.json())
541
  .then(data => {
542
  if (data.success) {
543
+ console.log('登录成功,保存 token');
544
  localStorage.setItem('authToken', data.token);
545
+ isLoggedIn = true;
546
  hideLoginForm();
547
+ // 手动更新 UI 状态
548
+ document.getElementById('loginButton').style.display = 'none';
549
+ document.getElementById('logoutButton').style.display = 'block';
550
+ updateActionButtons(true);
551
  } else {
552
+ console.log('登录失败:', data.message);
553
  loginError.textContent = data.message || '登录失败';
554
  loginError.style.display = 'block';
555
  }
 
573
  })
574
  .then(response => response.json())
575
  .then(data => {
576
+ console.log('登出成功,清除 token');
577
  localStorage.removeItem('authToken');
578
+ isLoggedIn = false;
579
+ document.getElementById('loginButton').style.display = 'block';
580
+ document.getElementById('logoutButton').style.display = 'none';
581
+ updateActionButtons(false);
582
  })
583
  .catch(error => {
584
+ console.error('登出失败,但仍清除 token:', error);
585
  localStorage.removeItem('authToken');
586
+ isLoggedIn = false;
587
+ document.getElementById('loginButton').style.display = 'block';
588
+ document.getElementById('logoutButton').style.display = 'none';
589
+ updateActionButtons(false);
590
  });
591
+ } else {
592
+ console.log('本地无 token,直接设置为未登录');
593
+ isLoggedIn = false;
594
+ document.getElementById('loginButton').style.display = 'block';
595
+ document.getElementById('logoutButton').style.display = 'none';
596
+ updateActionButtons(false);
597
  }
598
  }
599
 
600
+ function updateActionButtons(loggedIn) {
601
+ console.log('更新操作按钮状态,是否已登录:', loggedIn);
602
+ isLoggedIn = loggedIn;
603
  const cards = document.querySelectorAll('.server-card');
604
  cards.forEach(card => {
605
  const buttons = card.querySelector('.action-buttons');
606
  if (buttons) {
607
+ buttons.style.display = loggedIn ? 'flex' : 'none';
608
  }
609
  });
610
  }
611
 
612
+ // 使用 window.onload 确保页面完全加载后检查登录状态
613
+ window.onload = async function() {
614
+ console.log('页面加载完成,开始检查登录状态');
615
  await checkLoginStatus();
616
+ console.log('登录状态检查完成,初始化数据');
617
+ initialize();
618
+ };
619
 
620
  // 二次确认弹窗逻辑
621
  let pendingAction = null;
 
729
  }
730
  });
731
  updateSummary();
732
+ // 初始化完成后再次确保按钮状态正确
733
+ updateActionButtons(isLoggedIn);
734
  }
735
 
 
 
 
 
 
 
736
  function renderInstanceCard(instance) {
737
  const instanceId = instance.repo_id;
738
  instanceMap.set(instanceId, instance);
 
794
  <div class="metric-value download">N/A</div>
795
  </div>
796
  </div>
797
+ <div class="action-buttons" style="display: ${isLoggedIn ? 'flex' : 'none'};">
798
  <button class="action-button" onclick="showConfirmDialog('restart', '${instance.repo_id}', '确认重启', '您确定要重启实例 ${instance.name} (${instance.repo_id}) 吗?')">重启</button>
799
+ <button class="action-button" onclick="showConfirmDialog('rebuild', '${instance.repo_id}', '确认重建', '您确定要重建实例 ${instance.name} (${instance.repo_id}) 吗?重建将从头开始构建,可能会清除缓存和设置。')">重建</button>
800
  </div>
801
  `;
802
  userServers.appendChild(card);
 
866
  async function restartSpace(repoId) {
867
  try {
868
  const token = localStorage.getItem('authToken');
869
+ if (!token || !isLoggedIn) {
870
  alert('请先登录以执行此操作');
871
  showLoginForm();
872
  return;
 
885
  if (response.status === 401) {
886
  alert('登录已过期,请重新登录');
887
  localStorage.removeItem('authToken');
888
+ isLoggedIn = false;
889
+ document.getElementById('loginButton').style.display = 'block';
890
+ document.getElementById('logoutButton').style.display = 'none';
891
+ updateActionButtons(false);
892
  showLoginForm();
893
  } else {
894
  alert(`重启失败: ${result.error || '未知错误'}`);
 
904
  async function rebuildSpace(repoId) {
905
  try {
906
  const token = localStorage.getItem('authToken');
907
+ if (!token || !isLoggedIn) {
908
  alert('请先登录以执行此操作');
909
  showLoginForm();
910
  return;
 
923
  if (response.status === 401) {
924
  alert('登录已过期,请重新登录');
925
  localStorage.removeItem('authToken');
926
+ isLoggedIn = false;
927
+ document.getElementById('loginButton').style.display = 'block';
928
+ document.getElementById('logoutButton').style.display = 'none';
929
+ updateActionButtons(false);
930
  showLoginForm();
931
  } else {
932
  alert(`重建失败: ${result.error || '未知错误'}`);