Files
pdf-translate-web/templates/admin/stats.html
coder db98c2b82c refactor: 备用大模型整合到大模型配置页
- 备用大模型不再单独页面,直接在大模型配置页显示
- 新增/编辑使用模态框,更简洁高效
- 移除独立的 backup_llm.html 和 backup_llm_form.html
- 统一侧边栏导航,移除备用大模型链接
- API 改为只返回 JSON,不再渲染页面
2026-04-16 15:58:17 +08:00

165 lines
8.1 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>统计报表 - 后台管理</title>
<link rel="icon" href="/static/img/favicon.svg" type="image/svg+xml">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
body { background-color: #f5f5f5; }
.sidebar { position: fixed; top: 0; left: 0; height: 100vh; width: 250px; background: #343a40; padding-top: 60px; }
.sidebar .nav-link { color: #adb5bd; padding: 12px 20px; }
.sidebar .nav-link:hover, .sidebar .nav-link.active { color: #fff; background: rgba(255,255,255,0.1); }
.main-content { margin-left: 250px; padding: 20px; }
</style>
</head>
<body>
<nav class="sidebar">
<div class="position-absolute top-0 w-100 p-3 border-bottom border-secondary">
<h5 class="text-white mb-0"><i class="bi bi-gear-fill"></i> 后台管理</h5>
</div>
<ul class="nav flex-column">
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.dashboard') }}"><i class="bi bi-speedometer2"></i> 数据概览</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.users') }}"><i class="bi bi-people"></i> 用户管理</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.translations') }}"><i class="bi bi-file-text"></i> 翻译记录</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.cache_list') }}"><i class="bi bi-database"></i> 缓存管理</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.packages') }}"><i class="bi bi-box-seam"></i> 数据包套餐</a></li>
<li class="nav-item"><a class="nav-link active" href="{{ url_for('admin.stats') }}"><i class="bi bi-bar-chart"></i> 统计报表</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.logs') }}"><i class="bi bi-list-check"></i> 操作日志</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.llm_config') }}"><i class="bi bi-cpu"></i> 大模型配置</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.user_types') }}"><i class="bi bi-person-badge"></i> 用户类型</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.membership_plans') }}"><i class="bi bi-credit-card"></i> 会员套餐</a></li>
<li class="nav-item"><a class="nav-link " href="{{ url_for('admin.settings') }}"><i class="bi bi-sliders"></i> 系统配置</a></li>
</ul>
<div class="position-absolute bottom-0 w-100 p-3 border-top border-secondary">
<a href="/" class="btn btn-outline-light btn-sm w-100"><i class="bi bi-house"></i> 返回前台</a>
</div>
</nav>
<main class="main-content">
<div class="row mb-4">
<!-- 用户增长趋势 -->
<div class="col-md-6">
<div class="card">
<div class="card-header"><h6 class="mb-0"><i class="bi bi-people"></i> 用户增长趋势30天</h6></div>
<div class="card-body">
<canvas id="userChart" height="150"></canvas>
</div>
</div>
</div>
<!-- 翻译量趋势 -->
<div class="col-md-6">
<div class="card">
<div class="card-header"><h6 class="mb-0"><i class="bi bi-file-text"></i> 翻译量趋势30天</h6></div>
<div class="card-body">
<canvas id="transChart" height="150"></canvas>
</div>
</div>
</div>
</div>
<div class="row mb-4">
<!-- 用户类型分布 -->
<div class="col-md-4">
<div class="card">
<div class="card-header"><h6 class="mb-0"><i class="bi bi-pie-chart"></i> 用户类型分布</h6></div>
<div class="card-body">
<canvas id="userTypeChart" height="200"></canvas>
</div>
</div>
</div>
<!-- 翻译状态分布 -->
<div class="col-md-4">
<div class="card">
<div class="card-header"><h6 class="mb-0"><i class="bi bi-pie-chart"></i> 翻译状态分布</h6></div>
<div class="card-body">
<canvas id="statusChart" height="200"></canvas>
</div>
</div>
</div>
<!-- Top用户 -->
<div class="col-md-4">
<div class="card">
<div class="card-header"><h6 class="mb-0"><i class="bi bi-trophy"></i> 活跃用户Top10</h6></div>
<div class="card-body p-0">
<table class="table table-sm mb-0">
<thead class="table-light">
<tr><th>排名</th><th>用户</th><th>翻译数</th></tr>
</thead>
<tbody>
{% for name, count in top_users %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ name }}</td>
<td><span class="badge bg-primary">{{ count }}</span></td>
</tr>
{% else %}
<tr><td colspan="3" class="text-center text-muted">暂无数据</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
<script>
// 用户增长趋势
new Chart(document.getElementById('userChart'), {
type: 'line',
data: {
labels: {{ user_growth | map(attribute='date') | list | tojson }},
datasets: [{
label: '新增用户',
data: {{ user_growth | map(attribute='count') | list | tojson }},
borderColor: '#0d6efd',
backgroundColor: 'rgba(13, 110, 253, 0.1)',
fill: true, tension: 0.3
}]
},
options: { responsive: true, plugins: { legend: { display: false } } }
});
// 翻译量趋势
new Chart(document.getElementById('transChart'), {
type: 'bar',
data: {
labels: {{ translation_growth | map(attribute='date') | list | tojson }},
datasets: [{
label: '翻译次数',
data: {{ translation_growth | map(attribute='count') | list | tojson }},
backgroundColor: 'rgba(25, 135, 84, 0.7)'
}]
},
options: { responsive: true, plugins: { legend: { display: false } } }
});
// 用户类型分布
new Chart(document.getElementById('userTypeChart'), {
type: 'doughnut',
data: {
labels: {{ user_distribution | map(attribute=0) | list | tojson }},
datasets: [{
data: {{ user_distribution | map(attribute=1) | list | tojson }},
backgroundColor: ['#6c757d', '#ffc107', '#fd7e14', '#0d6efd', '#198754']
}]
}
});
// 翻译状态分布
new Chart(document.getElementById('statusChart'), {
type: 'doughnut',
data: {
labels: {{ status_distribution | map(attribute=0) | list | tojson }},
datasets: [{
data: {{ status_distribution | map(attribute=1) | list | tojson }},
backgroundColor: ['#198754', '#ffc107', '#dc3545', '#6c757d']
}]
}
});
</script>
</body>
</html>