{% extends "base.html" %} {% block title %} 机器人详情 - Amrita Dashboard{%
endblock %} {% block extra_head %}
<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
{% endblock %} {% block extra_css %}
<style>
  .chart-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 15px;
    box-sizing: border-box;
  }

  .gauge-container {
    position: relative;
    width: 100%;
    max-width: 200px;
    height: auto;
    margin: 0 auto;
  }

  .gauge-container canvas {
    width: 100% !important;
    height: auto !important;
    max-height: 150px;
    display: block;
  }

  .gauge-value {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    width: 100%;
  }

  @media (max-width: 768px) {
    .info-grid {
      grid-template-columns: 1fr;
    }
    .charts-grid {
      grid-template-columns: 1fr;
    }
    .card-header {
      flex-direction: column;
      align-items: flex-start;
    }
    .refresh-btn {
      margin-top: 10px;
    }
    .chart-container {
      margin: 10px;
      height: auto;
      min-height: 180px;
    }
    .gauge-container {
      max-width: 150px;
    }
    .gauge-title {
      font-size: 14px;
    }
    .gauge-value {
      font-size: 20px;
      text-align: center;
      line-height: 1.5;
    }
  }
</style>
{% endblock %} {% block content %}
<div class="info-grid">
  <div class="info-card">
    <div class="card-header">
      <div class="card-title">机器人信息</div>
      <button class="refresh-btn" onclick="refreshData()">
        <i class="fas fa-sync-alt"></i> 刷新
      </button>
    </div>
    <div class="info-item">
      <span class="info-label">ID:</span>
      <span class="info-value" id="bot-id">{{ bot_static_info.id }}</span>
    </div>
    <!--
    <div class="info-item">
      <span class="info-label">Bot昵称:</span>
      <span class="info-value" id="bot-nickname"
        >{{ bot_static_info.bot_name }}</span
      >
    </div>
    -->
  </div>
  <div class="info-card">
    <div class="card-header">
      <div class="card-title">系统信息</div>
    </div>
    <div class="info-item">
      <span class="info-label">Bot名称:</span>
      <span class="info-value" id="bot-name">{{ bot_static_info.name }}</span>
    </div>
    <div class="info-item">
      <span class="info-label">操作系统:</span>
      <span class="info-value" id="system-os">{{ system_info.os }}</span>
    </div>
    <div class="info-item">
      <span class="info-label">Python版本:</span>
      <span class="info-value" id="system-python"
        >{{ system_info.python_version }}</span
      >
    </div>
    <div class="info-item">
      <span class="info-label">主机名:</span>
      <span class="info-value" id="system-hostname"
        >{{ system_info.hostname }}</span
      >
    </div>
    <div class="info-item">
      <span class="info-label">Amrita版本:</span>
      <span class="info-value" id="bot-version"
        >{{ bot_static_info.version }}</span
      >
    </div>
    <div class="info-item">
      <span class="info-label">运行协议:</span>
      <span class="info-value" id="bot-platform"
        >{{ bot_static_info.platform }}</span
      >
    </div>
  </div>
</div>
<div class="charts-grid">
  <div class="chart-card">
    <div class="card-header">
      <div class="card-title">CPU使用率</div>
    </div>
    <div class="chart-container">
      <div class="gauge-container">
        <canvas id="cpuGauge"></canvas>
        <div class="gauge-value" id="cpu-value">0%</div>
      </div>
    </div>
  </div>
  <div class="chart-card">
    <div class="card-header">
      <div class="card-title">内存使用率</div>
    </div>
    <div class="chart-container">
      <div class="gauge-container">
        <canvas id="memoryGauge"></canvas>
        <div class="gauge-value" id="memory-value">0%</div>
      </div>
    </div>
  </div>
  <div class="chart-card">
    <div class="card-header">
      <div class="card-title">磁盘使用率</div>
    </div>
    <div class="chart-container">
      <div class="gauge-container">
        <canvas id="diskGauge"></canvas>
        <div class="gauge-value" id="disk-value">0%</div>
      </div>
    </div>
  </div>
  <div class="info-card">
    <div class="card-header">
      <div class="card-title">网络流量</div>
    </div>
    <div class="info-item">
      <span class="info-label">发送:</span>
      <span class="info-value" id="network-sent">0 KB</span>
    </div>
    <div class="info-item">
      <span class="info-label">接收:</span>
      <span class="info-value" id="network-received">0 KB</span>
    </div>
    <div class="info-item">
      <span class="info-label">Bot状态:</span>
      <span class="info-value status-online" id="bot-status">在线</span>
    </div>
  </div>
</div>
{% endblock %} {% block scripts %}
<script>
  let refreshInterval;
  const REFRESH_INTERVAL_MS = 3000;
  let cpuGauge, memoryGauge, diskGauge;

  document.addEventListener("DOMContentLoaded", function () {
    initGauges();

    startAutoRefresh();
  });

  function initGauges() {
    const cpuCtx = document.getElementById("cpuGauge").getContext("2d");
    cpuGauge = new Chart(cpuCtx, {
      type: "doughnut",
      data: {
        datasets: [
          {
            data: [0, 100],
            backgroundColor: [
              "rgba(138, 43, 226, 0.8)",
              "rgba(200, 200, 200, 0.2)",
            ],
            borderWidth: 0,
          },
        ],
      },
      options: {
        cutout: "70%",
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: {
            display: false,
          },
          tooltip: {
            enabled: false,
          },
        },
      },
    });

    const memoryCtx = document.getElementById("memoryGauge").getContext("2d");
    memoryGauge = new Chart(memoryCtx, {
      type: "doughnut",
      data: {
        datasets: [
          {
            data: [0, 100],
            backgroundColor: [
              "rgba(46, 204, 113, 0.8)",
              "rgba(200, 200, 200, 0.2)",
            ],
            borderWidth: 0,
          },
        ],
      },
      options: {
        cutout: "70%",
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: {
            display: false,
          },
          tooltip: {
            enabled: false,
          },
        },
      },
    });

    const diskCtx = document.getElementById("diskGauge").getContext("2d");
    diskGauge = new Chart(diskCtx, {
      type: "doughnut",
      data: {
        datasets: [
          {
            data: [0, 100],
            backgroundColor: [
              "rgba(243, 156, 18, 0.8)",
              "rgba(200, 200, 200, 0.2)",
            ],
            borderWidth: 0,
          },
        ],
      },
      options: {
        cutout: "70%",
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: {
            display: false,
          },
          tooltip: {
            enabled: false,
          },
        },
      },
    });
  }

  function startAutoRefresh() {
    refreshData();

    refreshInterval = setInterval(refreshData, REFRESH_INTERVAL_MS);
  }

  function stopAutoRefresh() {
    if (refreshInterval) {
      clearInterval(refreshInterval);
    }
  }

  async function refreshData() {
    try {
      document.querySelectorAll(".refresh-btn i").forEach((icon) => {
        icon.classList.add("fa-spin");
      });

      const response = await fetch("/api/bot/status");
      const data = await response.json();

      updateGauge(cpuGauge, data.cpu_usage);
      updateGauge(memoryGauge, data.memory_usage);
      updateGauge(diskGauge, data.disk_usage);

      document.getElementById("cpu-value").textContent = `${data.cpu_usage}%`;
      document.getElementById(
        "memory-value"
      ).textContent = `${data.memory_usage}%`;
      document.getElementById("disk-value").textContent = `${data.disk_usage}%`;

      document.getElementById("network-sent").textContent = formatBytes(
        data.network_io.sent
      );
      document.getElementById("network-received").textContent = formatBytes(
        data.network_io.received
      );

      const statusElement = document.getElementById("bot-status");
      statusElement.textContent = data.status === "online" ? "在线" : "离线";
      statusElement.className = `info-value status-${data.status}`;
    } catch (error) {
      console.error("获取数据失败:", error);
      Swal.fire({
        title: "获取数据失败",
        text: "无法从服务器获取实时数据，请检查网络连接",
        icon: "error",
        timer: 2000,
      });
    } finally {
      document.querySelectorAll(".refresh-btn i").forEach((icon) => {
        icon.classList.remove("fa-spin");
      });
    }
  }

  function updateGauge(gauge, value) {
    gauge.data.datasets[0].data = [value, 100 - value];
    gauge.update();
  }

  function formatBytes(bytes, decimals = 2) {
    if (bytes === 0) return "0 Bytes";

    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ["Bytes", "KB", "MB", "GB", "TB"];

    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
  }

  window.addEventListener("beforeunload", function () {
    stopAutoRefresh();
  });
</script>
{% endblock %}
