Привязка данных LyngSat
This commit is contained in:
@@ -184,6 +184,27 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Link LyngSat Sources Card -->
|
||||
<div class="col-lg-6">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div class="bg-primary bg-opacity-10 rounded-circle p-2 me-3">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-link-45deg text-primary" viewBox="0 0 16 16">
|
||||
<path d="M4.715 6.542 3.343 7.914a3 3 0 1 0 4.243 4.243l1.828-1.829A3 3 0 0 0 8.586 5.5L8 6.086a1.002 1.002 0 0 0-.154.199 2 2 0 0 1 .861 3.337L6.88 11.45a2 2 0 1 1-2.83-2.83l.793-.792a4.018 4.018 0 0 1-.128-1.287z"/>
|
||||
<path d="M6.586 4.672A3 3 0 0 0 7.414 9.5l.775-.776a2 2 0 0 1-.896-3.346L9.12 3.55a2 2 0 1 1 2.83 2.83l-.793.792c.112.42.155.855.128 1.287l1.372-1.372a3 3 0 1 0-4.243-4.243z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="card-title mb-0">Привязка источников LyngSat</h3>
|
||||
</div>
|
||||
<p class="card-text">Автоматическая привязка источников из базы LyngSat к объектам по частоте и поляризации. Объекты с привязанными источниками отображаются как "ТВ".</p>
|
||||
<a href="{% url 'mainapp:link_lyngsat' %}" class="btn btn-primary">
|
||||
Привязать источники
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
90
dbapp/mainapp/templates/mainapp/link_lyngsat.html
Normal file
90
dbapp/mainapp/templates/mainapp/link_lyngsat.html
Normal file
@@ -0,0 +1,90 @@
|
||||
{% extends 'mainapp/base.html' %}
|
||||
|
||||
{% block title %}Привязка источников LyngSat{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h3 class="mb-0">
|
||||
<i class="bi bi-link-45deg"></i> Привязка источников LyngSat к объектам
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- Alert messages -->
|
||||
{% include 'mainapp/components/_messages.html' %}
|
||||
|
||||
<div class="alert alert-info" role="alert">
|
||||
<i class="bi bi-info-circle"></i>
|
||||
<strong>Информация:</strong> Эта функция автоматически привязывает источники из базы LyngSat к объектам
|
||||
на основе совпадения частоты (с округлением) и поляризации. Объекты с привязанными источниками LyngSat
|
||||
будут отмечены как "ТВ" в списке объектов.
|
||||
</div>
|
||||
|
||||
<form method="post" class="needs-validation" novalidate>
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="{{ form.satellites.id_for_label }}" class="form-label">
|
||||
{{ form.satellites.label }}
|
||||
</label>
|
||||
{{ form.satellites }}
|
||||
{% if form.satellites.help_text %}
|
||||
<div class="form-text">{{ form.satellites.help_text }}</div>
|
||||
{% endif %}
|
||||
{% if form.satellites.errors %}
|
||||
<div class="invalid-feedback d-block">
|
||||
{{ form.satellites.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="{{ form.frequency_tolerance.id_for_label }}" class="form-label">
|
||||
{{ form.frequency_tolerance.label }}
|
||||
</label>
|
||||
{{ form.frequency_tolerance }}
|
||||
{% if form.frequency_tolerance.help_text %}
|
||||
<div class="form-text">{{ form.frequency_tolerance.help_text }}</div>
|
||||
{% endif %}
|
||||
{% if form.frequency_tolerance.errors %}
|
||||
<div class="invalid-feedback d-block">
|
||||
{{ form.frequency_tolerance.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<button type="submit" class="btn btn-primary btn-lg">
|
||||
<i class="bi bi-link-45deg"></i> Привязать источники
|
||||
</button>
|
||||
<a href="{% url 'mainapp:actions' %}" class="btn btn-secondary">
|
||||
<i class="bi bi-arrow-left"></i> Назад к действиям
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Help section -->
|
||||
<div class="card mt-4 shadow-sm">
|
||||
<div class="card-header bg-light">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-question-circle"></i> Как это работает?
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ol class="mb-0">
|
||||
<li>Система округляет частоту каждого объекта до целого числа</li>
|
||||
<li>Ищет источники LyngSat с той же поляризацией и близкой частотой (в пределах допуска)</li>
|
||||
<li>При нахождении совпадения создается связь между объектом и источником LyngSat</li>
|
||||
<li>Объекты с привязанными источниками отображаются как "ТВ" в списке</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -251,6 +251,12 @@
|
||||
onchange="toggleColumn(this)"> Стандарт
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label class="dropdown-item">
|
||||
<input type="checkbox" class="column-toggle" data-column="24" checked
|
||||
onchange="toggleColumn(this)"> Тип источника
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -463,6 +469,7 @@
|
||||
{% include 'mainapp/components/_table_header.html' with label="Комментарий" field="" sortable=False %}
|
||||
{% include 'mainapp/components/_table_header.html' with label="Усреднённое" field="" sortable=False %}
|
||||
{% include 'mainapp/components/_table_header.html' with label="Стандарт" field="standard" sort=sort %}
|
||||
{% include 'mainapp/components/_table_header.html' with label="Тип источника" field="" sortable=False %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -495,10 +502,19 @@
|
||||
<td>{{ item.comment }}</td>
|
||||
<td>{{ item.is_average }}</td>
|
||||
<td>{{ item.standard }}</td>
|
||||
<td>
|
||||
{% if item.obj.lyngsat_source %}
|
||||
<a href="#" class="text-primary text-decoration-none" onclick="showLyngsatModal({{ item.obj.lyngsat_source.id }}); return false;">
|
||||
<i class="bi bi-tv"></i> ТВ
|
||||
</a>
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="22" class="text-center py-4">
|
||||
<td colspan="25" class="text-center py-4">
|
||||
{% if selected_satellite_id %}
|
||||
Нет данных для выбранных фильтров
|
||||
{% else %}
|
||||
@@ -1165,4 +1181,160 @@
|
||||
|
||||
<!-- Include the selected items offcanvas component -->
|
||||
{% include 'mainapp/components/_selected_items_offcanvas.html' %}
|
||||
|
||||
<!-- LyngSat Data Modal -->
|
||||
<div class="modal fade" id="lyngsatModal" tabindex="-1" aria-labelledby="lyngsatModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title" id="lyngsatModalLabel">
|
||||
<i class="bi bi-tv"></i> Данные источника LyngSat
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Закрыть"></button>
|
||||
</div>
|
||||
<div class="modal-body" id="lyngsatModalBody">
|
||||
<div class="text-center py-4">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Загрузка...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showLyngsatModal(lyngsatId) {
|
||||
// Показываем модальное окно
|
||||
const modal = new bootstrap.Modal(document.getElementById('lyngsatModal'));
|
||||
modal.show();
|
||||
|
||||
// Показываем индикатор загрузки
|
||||
const modalBody = document.getElementById('lyngsatModalBody');
|
||||
modalBody.innerHTML = `
|
||||
<div class="text-center py-4">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Загрузка...</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Загружаем данные
|
||||
fetch(`/api/lyngsat/${lyngsatId}/`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Ошибка загрузки данных');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
// Формируем HTML с данными
|
||||
let html = `
|
||||
<div class="container-fluid">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-light">
|
||||
<strong><i class="bi bi-info-circle"></i> Основная информация</strong>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm table-borderless mb-0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-muted" style="width: 40%;">Спутник:</td>
|
||||
<td><strong>${data.satellite}</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted">Частота:</td>
|
||||
<td><strong>${data.frequency} МГц</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted">Поляризация:</td>
|
||||
<td><span class="badge bg-info">${data.polarization}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted">Канал:</td>
|
||||
<td>${data.channel_info}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-light">
|
||||
<strong><i class="bi bi-gear"></i> Технические параметры</strong>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm table-borderless mb-0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-muted" style="width: 40%;">Модуляция:</td>
|
||||
<td><span class="badge bg-secondary">${data.modulation}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted">Стандарт:</td>
|
||||
<td><span class="badge bg-secondary">${data.standard}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted">Сим. скорость:</td>
|
||||
<td><strong>${data.sym_velocity} БОД</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted">FEC:</td>
|
||||
<td>${data.fec}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-light">
|
||||
<strong><i class="bi bi-clock-history"></i> Дополнительная информация</strong>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p class="mb-2">
|
||||
<span class="text-muted">Последнее обновление:</span><br>
|
||||
<strong>${data.last_update}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
${data.url ? `
|
||||
<p class="mb-2">
|
||||
<span class="text-muted">Ссылка на источник:</span><br>
|
||||
<a href="${data.url}" target="_blank" class="btn btn-sm btn-outline-primary">
|
||||
<i class="bi bi-link-45deg"></i> Открыть на LyngSat
|
||||
</a>
|
||||
</p>
|
||||
` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
modalBody.innerHTML = html;
|
||||
})
|
||||
.catch(error => {
|
||||
modalBody.innerHTML = `
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<i class="bi bi-exclamation-triangle"></i> ${error.message}
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user