domovoy_bot/web/templates/infra.html

172 lines
7.2 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.

{% extends "base.html" %}
{% block title %}Инфраструктура - МКД ЛенКом 37{% endblock %}
{% block nav_infra %}active{% endblock %}
{% block content %}
<div class="mb-3">
<h4 class="mb-1" style="font-size: 16px; font-weight: bold;">Мониторинг инфраструктуры и сервисов</h4>
<div class="small text-muted">Состояние сетевых узлов, замеры интернет-канала и статус фоновых пайплайнов</div>
</div>
<div class="row g-3 mb-3">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span>ТЕСТЫ СКОРОСТИ ИНТЕРНЕТ-КАНАЛА (ТАРИФ 150 МБИТ/С)</span>
<button id="runSpeedtestBtn" class="btn-unix">
<i class="bi bi-play-fill"></i> Запустить замер сейчас
</button>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table mb-0">
<thead>
<tr>
<th>Дата и время</th>
<th>Download (Мбит/с)</th>
<th>Upload (Мбит/с)</th>
<th>Ping (мс)</th>
<th>Сервер замера</th>
</tr>
</thead>
<tbody>
{% for test in speedtests %}
<tr>
<td>{{ test.timestamp }}</td>
<td><b>{{ test.download }}</b></td>
<td><b>{{ test.upload }}</b></td>
<td>{{ test.ping }}</td>
<td class="text-muted">{{ test.server_name }}</td>
</tr>
{% else %}
<tr>
<td colspan="5" class="text-center text-muted py-3">Данных замеров пока нет</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="row g-3">
<div class="col-md-6">
<div class="card h-100">
<div class="card-header">СЕТЕВЫЕ УЗЛЫ И ХОСТЫ</div>
<div class="card-body p-0">
<table class="table mb-0">
<tbody>
<tr>
<td style="width: 140px;"><b>NanoPi R3S</b></td>
<td>192.168.10.1 (Роутер / Шлюз)</td>
<td class="text-end"><span class="badge-status badge-success">ONLINE</span></td>
</tr>
<tr>
<td><b>Synology NAS</b></td>
<td>192.168.10.105 (Хранилище / PostgreSQL)</td>
<td class="text-end"><span class="badge-status badge-success">ONLINE</span></td>
</tr>
<tr>
<td><b>DockerServer</b></td>
<td>192.168.10.116 (Domovoy / Maya Bot)</td>
<td class="text-end"><span class="badge-status badge-success">ONLINE</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<span>ГИС ЖКХ & СБОРКА АРХИВА</span>
<span id="gisStatusBadge" class="badge-status">СТАТУС: ПРОВЕРКА</span>
</div>
<div class="card-body">
<div class="d-flex gap-2 mb-2">
<button id="runGisHarvestBtn" class="btn-unix btn-unix-primary flex-grow-1">
<i class="bi bi-cloud-download"></i> Запустить сборку ГИС ЖКХ
</button>
<button id="refreshGisStatusBtn" class="btn-unix">
Обновить статус
</button>
</div>
<div class="small text-muted mb-1">Лог выполнения процесса:</div>
<pre id="gisLogs" style="height: 160px; overflow-y: scroll; background-color: #ffffff; border: 1px solid var(--border-color); font-size: 11px;"></pre>
</div>
</div>
</div>
</div>
<script>
document.getElementById('runSpeedtestBtn').addEventListener('click', async function() {
const btn = this;
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Замер (до 60 сек)...';
try {
const response = await fetch('/api/infra/run_speedtest', { method: 'POST' });
const result = await response.json();
alert(result.message);
location.reload();
} catch (e) {
alert('Ошибка: ' + e);
} finally {
btn.disabled = false;
btn.innerHTML = '<i class="bi bi-play-fill"></i> Запустить замер сейчас';
}
});
document.getElementById('runGisHarvestBtn').addEventListener('click', async function() {
const btn = this;
if (!confirm('Запустить сборку ГИС ЖКХ? Это займет некоторое время.')) return;
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Процесс запущен...';
try {
const response = await fetch('/api/infra/run_gis_harvest', { method: 'POST' });
const result = await response.json();
alert(result.message);
} catch (e) {
alert('Ошибка: ' + e);
} finally {
btn.disabled = false;
btn.innerHTML = '<i class="bi bi-cloud-download"></i> Запустить сборку ГИС ЖКХ';
refreshGisStatus();
}
});
async function refreshGisStatus() {
const badge = document.getElementById('gisStatusBadge');
const logs = document.getElementById('gisLogs');
try {
const response = await fetch('/api/infra/gis_status');
const data = await response.json();
if (data.alive) {
badge.className = 'badge-status badge-success';
badge.innerText = 'РАБОТАЕТ';
} else {
badge.className = 'badge-status';
badge.innerText = 'ОЖИДАНИЕ';
}
logs.innerText = data.log || 'Лог чист';
logs.scrollTop = logs.scrollHeight;
} catch (e) {
badge.className = 'badge-status badge-danger';
badge.innerText = 'ОШИБКА';
}
}
document.getElementById('refreshGisStatusBtn').addEventListener('click', refreshGisStatus);
window.addEventListener('load', refreshGisStatus);
setInterval(refreshGisStatus, 30000);
</script>
{% endblock %}