154 lines
5.7 KiB
HTML
154 lines
5.7 KiB
HTML
|
|
{% extends 'base.html' %}
|
|||
|
|
{% block title %}运营面板 - 统计与监控{% endblock %}
|
|||
|
|
{% block content %}
|
|||
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|||
|
|
<h3>统计与监控</h3>
|
|||
|
|
<div>
|
|||
|
|
<a class="btn btn-outline-secondary" href="{% url 'admin_panel:dashboard' %}">返回概览</a>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<form method="get" class="row g-2 mb-3">
|
|||
|
|
<div class="col-md-3">
|
|||
|
|
<input type="number" name="days" value="{{ days }}" class="form-control" placeholder="展示天数(默认14)" />
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-2">
|
|||
|
|
<button class="btn btn-primary" type="submit">刷新</button>
|
|||
|
|
</div>
|
|||
|
|
</form>
|
|||
|
|
|
|||
|
|
<div class="row g-3">
|
|||
|
|
<div class="col-md-6">
|
|||
|
|
<div class="card">
|
|||
|
|
<div class="card-body">
|
|||
|
|
<h5 class="card-title">平台每日总流量(GB)</h5>
|
|||
|
|
<canvas id="platformDailyChart" height="120" class="mb-3" style="width: 100%;"></canvas>
|
|||
|
|
<div class="table-responsive">
|
|||
|
|
<table class="table table-sm table-striped">
|
|||
|
|
<thead>
|
|||
|
|
<tr><th>日期</th><th>GB</th></tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
{% for r in daily_rows %}
|
|||
|
|
<tr><td>{{ r.day }}</td><td>{{ r.gb }}</td></tr>
|
|||
|
|
{% empty %}
|
|||
|
|
<tr><td colspan="2" class="text-center">暂无数据</td></tr>
|
|||
|
|
{% endfor %}
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="col-md-6">
|
|||
|
|
<div class="card">
|
|||
|
|
<div class="card-body">
|
|||
|
|
<h5 class="card-title">本月域名流量 Top 20(GB)</h5>
|
|||
|
|
<div class="table-responsive">
|
|||
|
|
<table class="table table-sm table-striped">
|
|||
|
|
<thead>
|
|||
|
|
<tr><th>域名</th><th>GB</th></tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
{% for t in top_domains %}
|
|||
|
|
<tr><td>{{ t.domain.name }}</td><td>{{ t.gb }}</td></tr>
|
|||
|
|
{% empty %}
|
|||
|
|
<tr><td colspan="2" class="text-center">暂无数据</td></tr>
|
|||
|
|
{% endfor %}
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="row g-3 mt-1">
|
|||
|
|
<div class="col-md-12">
|
|||
|
|
<div class="card">
|
|||
|
|
<div class="card-body">
|
|||
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|||
|
|
<h5 class="card-title mb-0">异常域名(根据阈值检测)</h5>
|
|||
|
|
<div class="text-muted small">
|
|||
|
|
阈值:倍率 {{ anomaly_config.multiplier }} ×,窗口 {{ anomaly_config.window_days }} 天,最低 {{ anomaly_config.min_gb }} GB
|
|||
|
|
,<a href="{% url 'admin_panel:settings' %}">调整参数</a>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
{% if not anomaly_config.enabled %}
|
|||
|
|
<div class="alert alert-secondary">异常检测已关闭,可在系统设置中开启。</div>
|
|||
|
|
{% endif %}
|
|||
|
|
<div class="table-responsive">
|
|||
|
|
<table class="table table-sm table-striped">
|
|||
|
|
<thead>
|
|||
|
|
<tr><th>域名</th><th>今日GB</th><th>过去均值GB</th><th>倍率</th><th>查看</th><th>操作</th></tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
{% for a in anomalies %}
|
|||
|
|
<tr class="table-warning">
|
|||
|
|
<td>{{ a.domain.name }}</td>
|
|||
|
|
<td>{{ a.today_gb }}</td>
|
|||
|
|
<td>{{ a.past_avg_gb }}</td>
|
|||
|
|
<td>{% if a.ratio %}×{{ a.ratio }}{% else %}-{% endif %}</td>
|
|||
|
|
<td>
|
|||
|
|
<a class="btn btn-sm btn-outline-primary" href="/domains/{{ a.domain.id }}/">用户侧详情</a>
|
|||
|
|
</td>
|
|||
|
|
<td>
|
|||
|
|
<form method="post" action="{% url 'admin_panel:domain_toggle_suspend' a.domain.id %}" class="d-inline" onsubmit="return confirm('确定切换暂停/恢复该域名吗?');">
|
|||
|
|
{% csrf_token %}
|
|||
|
|
<button class="btn btn-sm btn-outline-warning" type="submit">暂停/恢复</button>
|
|||
|
|
</form>
|
|||
|
|
<a class="btn btn-sm btn-outline-secondary" href="{% url 'admin_panel:domain_switch_plan' a.domain.id %}">切换套餐</a>
|
|||
|
|
<a class="btn btn-sm btn-outline-success" href="{% url 'admin_panel:domain_grant_traffic' a.domain.id %}">流量赠送</a>
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
{% empty %}
|
|||
|
|
<tr><td colspan="6" class="text-center">暂无异常域名</td></tr>
|
|||
|
|
{% endfor %}
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
{% endblock %}
|
|||
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
|
|||
|
|
<script>
|
|||
|
|
document.addEventListener('DOMContentLoaded', function(){
|
|||
|
|
var rows = [
|
|||
|
|
{% for r in daily_rows %}
|
|||
|
|
{ day: '{{ r.day|date:"Y-m-d" }}', gb: {{ r.gb|default:0 }} },
|
|||
|
|
{% endfor %}
|
|||
|
|
];
|
|||
|
|
var el = document.getElementById('platformDailyChart');
|
|||
|
|
if (!el || !rows.length || !window.Chart) return;
|
|||
|
|
var ctx = el.getContext('2d');
|
|||
|
|
var labels = rows.map(function(x){ return x.day; });
|
|||
|
|
var dataGb = rows.map(function(x){ return x.gb || 0; });
|
|||
|
|
new Chart(ctx, {
|
|||
|
|
type: 'line',
|
|||
|
|
data: {
|
|||
|
|
labels: labels,
|
|||
|
|
datasets: [{
|
|||
|
|
label: '平台总流量(GB)',
|
|||
|
|
data: dataGb,
|
|||
|
|
borderColor: '#198754',
|
|||
|
|
backgroundColor: 'rgba(25,135,84,0.15)',
|
|||
|
|
fill: true,
|
|||
|
|
tension: 0.3
|
|||
|
|
}]
|
|||
|
|
},
|
|||
|
|
options: {
|
|||
|
|
responsive: true,
|
|||
|
|
interaction: { mode: 'index', intersect: false },
|
|||
|
|
plugins: {
|
|||
|
|
legend: { position: 'bottom' },
|
|||
|
|
tooltip: { callbacks: { label: function(ctx){ return ctx.dataset.label + ': ' + ctx.formattedValue + ' GB'; } } }
|
|||
|
|
},
|
|||
|
|
scales: {
|
|||
|
|
y: { title: { display: true, text: 'GB' } }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
</script>
|