Spaces:
Running
Running
<html lang="zh-CN"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>AI API Dashboard</title> | |
<!-- 引入 Bootstrap 5 与 Bootstrap Icons --> | |
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> | |
<!-- 引入 Google Fonts: Poppins --> | |
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&display=swap" rel="stylesheet"> | |
<style> | |
/* 基本样式 */ | |
body { | |
font-family: 'Poppins', sans-serif; | |
background: linear-gradient(135deg, #f5f7fa, #e9eff5); | |
color: #333; | |
line-height: 1.7; | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
} | |
.container { | |
max-width: 1100px; | |
padding: 20px; | |
} | |
h1 { | |
font-weight: 700; | |
color: #3f51b5; /* Material Indigo 500 */ | |
text-align: center; | |
margin-bottom: 0.6em; | |
letter-spacing: -0.5px; | |
} | |
p.lead { | |
text-align: center; | |
font-size: 1.2rem; | |
color: #606c76; | |
} | |
/* Dashboard Section 样式 */ | |
.dashboard-section { | |
background-color: #fff; | |
border-radius: 12px; | |
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.06); | |
margin-bottom: 40px; | |
padding: 30px; | |
border: none; | |
transition: transform 0.3s ease; | |
} | |
.dashboard-section:hover { | |
transform: translateY(-5px); | |
} | |
.dashboard-section h2 { | |
font-weight: 600; | |
color: #424242; | |
margin-bottom: 1.6rem; | |
padding-bottom: 10px; | |
border-bottom: 2px solid #e0e0e0; | |
} | |
/* 卡片样式 */ | |
.metrics-card { | |
background-color: #fff; | |
border: none; | |
border-radius: 10px; | |
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); | |
padding: 25px; | |
margin-bottom: 20px; | |
transition: transform 0.3s ease, box-shadow 0.3s ease; | |
} | |
.metrics-card:hover { | |
transform: translateY(-3px); | |
box-shadow: 0 12px 25px rgba(0, 0, 0, 0.08); | |
border-top: 3px solid #3f51b5; | |
} | |
.card-title { | |
display: flex; | |
align-items: center; | |
font-size: 1.1rem; | |
font-weight: 600; | |
color: #37474f; | |
margin-bottom: 1.2rem; | |
} | |
.card-title i { | |
margin-right: 8px; | |
font-size: 1.3rem; | |
color: #8e44ad; | |
} | |
.metrics-card p { | |
font-size: 1rem; | |
margin-bottom: 0.8rem; | |
} | |
.badge { | |
font-size: 1rem; | |
font-weight: 600; | |
padding: 0.5rem 0.75rem; | |
border-radius: 0.5rem; | |
} | |
/* 表格样式 */ | |
.key-balances-table { | |
width: 100%; | |
border-collapse: collapse; | |
margin-top: 20px; | |
border: 1px solid #e8e8e8; | |
border-radius: 8px; | |
overflow: hidden; | |
} | |
.key-balances-table th, | |
.key-balances-table td { | |
padding: 12px 15px; | |
text-align: left; | |
border-bottom: 1px solid #ecf0f1; | |
font-size: 0.95rem; | |
} | |
.key-balances-table thead { | |
background-color: #ecf0f1; | |
} | |
.key-balances-table th { | |
font-weight: 600; | |
text-transform: uppercase; | |
letter-spacing: 0.03em; | |
color: #2c3e50; | |
} | |
.key-balances-table tbody tr:nth-child(even) { | |
background-color: #f8f9fa; | |
} | |
.key-balances-table tbody tr:hover { | |
background-color: #f1f3f5; | |
} | |
.text-break { | |
word-break: break-word; | |
} | |
/* 页脚样式 */ | |
.footer { | |
text-align: center; | |
padding: 20px 0; | |
font-size: 0.9rem; | |
color: #888; | |
border-top: 1px solid #eee; | |
margin-top: 40px; | |
} | |
.footer a { | |
color: #888; | |
text-decoration: none; | |
} | |
.footer a:hover { | |
color: #2c3e50; | |
} | |
/* 响应式调节 */ | |
@media (max-width: 576px) { | |
h1 { font-size: 1.8rem; } | |
.card-title { font-size: 1rem; } | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container mt-5"> | |
<h1 class="text-center">AI API Dashboard</h1> | |
<p class="lead text-center">实时监控您的 API 代理服务状态</p> | |
<!-- 实时性能指标 --> | |
<section class="dashboard-section"> | |
<h2><i class="bi bi-speedometer2"></i> 实时性能指标</h2> | |
<div class="row"> | |
<div class="col-md-6 mb-4"> | |
<div class="card metrics-card"> | |
<div class="card-body"> | |
<h5 class="card-title"><i class="bi bi-lightning-fill"></i> 请求速率</h5> | |
<p>每分钟请求数 (RPM): <span class="badge bg-primary">{{ rpm }}</span></p> | |
<p>每日请求数 (RPD): <span class="badge bg-secondary">{{ rpd }}</span></p> | |
</div> | |
</div> | |
</div> | |
<div class="col-md-6"> | |
<div class="card metrics-card"> | |
<div class="card-body"> | |
<h5 class="card-title"><i class="bi bi-graph-up-arrow"></i> Token 使用量</h5> | |
<p>每分钟 Token 数 (TPM): <span class="badge bg-success">{{ tpm }}</span></p> | |
<p>每日 Token 数 (TPD): <span class="badge bg-info">{{ tpd }}</span></p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</section> | |
<!-- API 密钥余额 --> | |
<section class="dashboard-section"> | |
<h2><i class="bi bi-key-fill"></i> API 密钥余额</h2> | |
<div class="table-responsive"> | |
<table class="table key-balances-table"> | |
<thead> | |
<tr> | |
<th>API 密钥 (已打码)</th> | |
<th>余额</th> | |
</tr> | |
</thead> | |
<tbody> | |
{% for key_balance in key_balances %} | |
<tr> | |
<td class="text-break">{{ key_balance.key }}</td> | |
<td>{{ key_balance.balance }}</td> | |
</tr> | |
{% endfor %} | |
{% if not key_balances %} | |
<tr> | |
<td colspan="2">没有可用的 API 密钥信息。</td> | |
</tr> | |
{% endif %} | |
</tbody> | |
</table> | |
</div> | |
</section> | |
<div class="footer"> | |
<p>Dashboard created at {{ now }} · Powered by <a href="https://vercel.com" target="_blank" rel="noopener noreferrer">Vercel</a></p> | |
</div> | |
</div> | |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> | |
</body> | |
</html> |