New api and zone management; highligh occlusion and highlighAll functionality; improved search in reports and alerts history + autofill; refactored alert panel

This commit is contained in:
iv_vuytsik
2025-12-25 03:10:21 +03:00
parent 31030f2997
commit ce7e39debf
36 changed files with 1562 additions and 472 deletions

View File

@@ -116,7 +116,11 @@ class ReportView(ViewSet):
@extend_schema(
summary="Генерация отчета",
description="Генерирует отчет в выбранном формате (PDF или CSV)",
request={'application/json': {'type': 'object', 'properties': {'report_format': {'type': 'string', 'enum': ['pdf', 'csv']}}}},
request={'application/json': {'type': 'object', 'properties': {
'report_format': {'type': 'string', 'enum': ['pdf', 'csv']},
'hours': {'type': 'integer', 'description': 'Количество часов для фильтрации по времени'},
'detector_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Список ID датчиков для фильтрации (может быть числом или строкой вида "GLE-79")'}
}}},
methods=['POST'],
responses={
200: OpenApiResponse(
@@ -153,6 +157,10 @@ class ReportView(ViewSet):
status=status.HTTP_400_BAD_REQUEST
)
# Получаем параметры фильтрации
hours = request.data.get('hours')
detector_ids = request.data.get('detector_ids', [])
alerts = Alert.objects.select_related(
'sensor',
'sensor__signal_format',
@@ -163,6 +171,35 @@ class ReportView(ViewSet):
'sensor__zones__object'
).all()
# Фильтрация по времени (если указано количество часов)
if hours and isinstance(hours, (int, float)) and hours > 0:
from datetime import timedelta
cutoff_time = timezone.now() - timedelta(hours=hours)
alerts = alerts.filter(created_at__gte=cutoff_time)
# Фильтрация по датчикам (если указаны ID)
if detector_ids and isinstance(detector_ids, list) and len(detector_ids) > 0:
# Конвертируем строковые ID в числовые ID базы данных
numeric_ids = []
for detector_id in detector_ids:
if isinstance(detector_id, (int, float)):
numeric_ids.append(int(detector_id))
elif isinstance(detector_id, str):
# Парсим строковые ID вида "GLE-79" или "GA-123"
try:
if '-' in detector_id:
# Формат "TYPE-ID" - извлекаем числовую часть
numeric_ids.append(int(detector_id.split('-')[-1]))
else:
# Предполагаем, что это просто число в строковом формате
numeric_ids.append(int(detector_id))
except (ValueError, IndexError):
# Пропускаем некорректные ID
continue
if numeric_ids:
alerts = alerts.filter(sensor_id__in=numeric_ids)
# текущая дата для имени файла
timestamp = timezone.now().strftime("%Y%m%d_%H%M%S")