ArgusSite/static/templates/videos/export.html

1020 lines
38 KiB
HTML
Raw Normal View History

2023-08-21 03:28:58 +00:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
2023-08-28 04:40:58 +00:00
<title>Экспорт записей</title>
2023-08-21 03:28:58 +00:00
<link rel="stylesheet" href="../styles/main.css" />
2023-08-22 15:29:23 +00:00
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
2023-08-21 03:28:58 +00:00
</head>
<body>
<header>
<img src="../img/argus.png">
2023-08-21 03:28:58 +00:00
<h1>Аргус</h1>
<h2><span>/</span> {{Organisation}}</h2>
</header>
<section class="account-info">
<div id="account-main">
<img id="person" src="../img/person.svg">
<span>{{User}}</span>
<img id="down" src="../img/down.svg">
<img id="up" src="../img/up.svg">
</div>
<a href="/logout"><div id="account-additional" class="additional">Выйти</div></a>
2023-08-21 03:28:58 +00:00
</section>
<section class="navigation">
<a href="/">
<div><img src="../img/chart.svg">Главная</div>
</a>
<a href="/devices">
<div><img src="../img/cloud.svg">Устройства</div>
</a>
<a href="/reports">
<div><img src="../img/bubble.svg">Отчёты</div>
</a>
<a href="/live">
<div><img src="../img/waves.svg">Трансляция</div>
</a>
<a href="/videos">
<div class="selected"><img src="../img/play.svg">Записи</div>
</a>
<a href="https://forms.yandex.ru/cloud/6515ecda3e9d08f17262c332/" target="_blank">
<div><img src="../img/bug.svg">Собщить об ошибке</div>
</a>
{{#if isAdmin}}
2023-09-11 05:59:00 +00:00
<a class="admin-panel" href="/admin">
<div><img src="../img/keyboard.svg">Админка</div>
2023-09-11 05:59:00 +00:00
</a>
{{/if}}
2023-08-28 04:40:58 +00:00
<a class="settings" href="/settings">
2023-08-21 03:28:58 +00:00
<div><img src="../img/gear.svg">Настройки</div>
</a>
</section>
<section class="main">
<section style="display: none;" class="dberror" id="exportLoading" >
<div class="erorr-container">
2023-09-17 12:22:14 +00:00
<div class="loader-container">
<div id="loader" class="loader">
<div class="square" id="sq1"></div>
<div class="square" id="sq2"></div>
<div class="square" id="sq3"></div>
<div class="square" id="sq4"></div>
<div class="square" id="sq5"></div>
<div class="square" id="sq6"></div>
<div class="square" id="sq7"></div>
<div class="square" id="sq8"></div>
<div class="square" id="sq9"></div>
</div>
2023-09-17 12:22:14 +00:00
</div>
<h1>Подготовка видео</h1> <br>
<span id="status">Пожалуйста, подождите..</span>
</div>
</section>
2023-09-17 12:22:14 +00:00
<section style="display: none;" class="dberror" id="dataLoading" >
<div class="loader-container">
<div class="loader">
<div class="square" id="sq11"></div>
<div class="square" id="sq12"></div>
<div class="square" id="sq13"></div>
<div class="square" id="sq14"></div>
<div class="square" id="sq15"></div>
<div class="square" id="sq16"></div>
<div class="square" id="sq17"></div>
<div class="square" id="sq18"></div>
<div class="square" id="sq19"></div>
</div>
</div>
</section>
2023-08-21 03:28:58 +00:00
{{#if ifDBError}}
<section class="dberror">
<div class="erorr-container">
<img src="../img/warning.svg"> <br>
<h1>Ошибка </h1> <br>
<span>Не удалось получить данные из БД</span>
<button type="button" onclick="location.reload();">Повторить попытку</button>
</div>
</section>
{{/if}}
<nav>
2023-08-28 04:40:58 +00:00
<a href="/videos">Воспроизведение</a>
<a class="selected" href="/videos/export">Экспорт</a>
2023-08-21 03:28:58 +00:00
</nav>
<section class="bg">
<section class="content">
<section style="min-height: 800px;" class="for-table">
2023-08-21 03:28:58 +00:00
<section class="organisation">
<h1>Организация</h1>
<ul class="area">
{{#each Groups}}
<li class="area-name"><img src="../img/ul.svg"><input type="checkbox" id="{{name}}" class="checkbox-input" hidden checked><label for="{{name}}" class="checkbox-label">{{name}}</label>
2023-08-21 03:28:58 +00:00
<ul class="area-devices" id="devices-1">
{{#each devices}}
<li class="device">
<img>
2023-09-17 12:22:14 +00:00
<input type="number" id="channels-{{this.serial}}" value="{{this.channels}}" hidden>
<input type="radio" name="camera-serial" id="radio-{{this.serial}}" class="radio-input" value="{{this.serial}}" hidden>
<label for="radio-{{this.serial}}" class="radio-label active-{{this.status}}">
2023-09-19 13:31:40 +00:00
{{#if this.number}}
{{this.number}}
{{else}}
{{this.serial}}
{{/if}}
</label>
</li>
{{/each}}
2023-08-21 03:28:58 +00:00
</ul>
</li>
{{/each}}
</ul>
2023-08-21 03:28:58 +00:00
</section>
<section class="table" style="position: relative;">
<div class="map">
<div id="map"></div>
</div>
2023-09-17 12:22:14 +00:00
<div style="background: white;" class="cameras">
<section style="border: 0;" class="whole-width">
<h1>Экспортировать запись с камеры</h1>
<h3>Выберите камеру, время и нажмите кнопку "Скачать запись"</h3>
<form id="edit-group-form">
<div class="parameters-input">
<label for="group-id">Камера</label>
<select name="group-id" id="group-id">
<option value="">Выберите номер камеры</option>
<option value="1">Камера 1</option>
<option value="2">Камера 2</option>
<option value="3">Камера 3</option>
<option value="4">Камера 4</option>
<option value="5">Камера 5</option>
<option value="6">Камера 6</option>
<option value="7">Камера 7</option>
<option value="8">Камера 8</option>
<option value="9">Камера 9</option>
<option value="10">Камера 10</option>
<option value="11">Камера 11</option>
<option value="12">Камера 12</option>
<option value="13">Камера 13</option>
</select>
2023-08-21 03:28:58 +00:00
</div>
2023-09-17 12:22:14 +00:00
</form>
<div style="margin-left: 44px; margin-right: 72px; width: calc(100% - 44px - 72px);" class="horizontal-line"></div>
<button style="margin-top: 15px;" id="group-edit" class="button-purple" type="button" onclick="playVideo();">Скачать запись</button>
</section>
2023-08-21 03:28:58 +00:00
</div>
<div class="calendar">
<div class="calendar-header">
<button id="prevMonth"></button>
<h2 id="monthYear"></h2>
<button id="nextMonth"></button>
</div>
<div class="daysOfWeek">
<div>Пн</div>
<div>Вт</div>
<div>Ср</div>
<div>Чт</div>
<div>Пт</div>
<div>Сб</div>
<div>Вс</div>
</div>
<div class="dates" id="dates">
</div>
</div>
<input type="hidden" id="selectedDate" name="selectedDate" hidden>
<div class="speedometr">
2023-08-28 11:25:45 +00:00
<div style="display: none;" id="speed-bg" class="speed-bg">
<h1>Данных для выбранного периода нет.</h1>
</div>
2023-08-21 03:28:58 +00:00
<h1>Скорость</h1>
<span>км/ч</span>
<span style="float: right; font-size: 18px;">1 ч</span>
<div>
<canvas id="speed"></canvas>
</div>
</div>
<div class="video-time">
2023-08-28 11:25:45 +00:00
<span style="margin-left: 15px;">с</span>
2023-08-21 03:28:58 +00:00
<input name="videoTime" type="time" id="video-time" step="1">
2023-08-28 11:25:45 +00:00
<span>до</span>
<input name="videoEndTime" type="time" id="video-end-time" step="1">
2023-08-21 03:28:58 +00:00
</div>
</section>
</section>
</section>
</section>
</section>
<style>
.table {
background-color:#f7f7fa !important;
2023-08-21 03:28:58 +00:00
}
.speedometr {
position: absolute;
right: 0;
bottom: 62px;
width: calc(75% - 300px - 10px - 32px);
height: 220px;
border-radius: 15px;
background-color: white;
padding-right: 32px;
}
.speedometr div {
2023-09-17 12:22:14 +00:00
height: 190px;
2023-08-21 03:28:58 +00:00
}
</style>
<script src="../scripts/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
2023-09-17 12:22:14 +00:00
<script>
function updateCameraOptions() {
var selectedSerial = document.querySelector('input[name="camera-serial"]:checked').value;
var channelsInput = document.querySelector('#channels-' + selectedSerial);
var numChannels = parseInt(channelsInput.value, 10);
var select = document.querySelector('#group-id');
select.innerHTML = '';
var defaultOption = document.createElement('option');
defaultOption.value = '';
defaultOption.textContent = 'Выберите номер камеры';
select.appendChild(defaultOption);
for (var i = 1; i <= numChannels; i++) {
var option = document.createElement('option');
option.value = i;
option.textContent = 'Камера ' + i;
select.appendChild(option);
}
}
</script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const areaNames = document.querySelectorAll('.area-name');
areaNames.forEach(function (areaName) {
const areaCheckbox = areaName.querySelector('.checkbox-input');
const deviceCheckboxes = areaName.querySelectorAll('.device .checkbox-input');
const deviceList = areaName.querySelector('.area-devices');
// Функция для скрытия/показа дочерних элементов
function toggleChildDevices(show) {
if (show) {
deviceList.style.display = 'block';
} else {
deviceList.style.display = 'none';
}
}
// Инициализация состояния чекбоксов и скрытия/показа дочерних элементов
toggleChildDevices(areaCheckbox.checked);
deviceCheckboxes.forEach(function (deviceCheckbox) {
deviceCheckbox.checked = areaCheckbox.checked;
});
areaCheckbox.addEventListener('change', function () {
const isChecked = areaCheckbox.checked;
deviceCheckboxes.forEach(function (deviceCheckbox) {
deviceCheckbox.checked = isChecked;
});
toggleChildDevices(isChecked);
});
deviceCheckboxes.forEach(function (deviceCheckbox) {
deviceCheckbox.addEventListener('change', function () {
const allUnchecked = Array.from(deviceCheckboxes).every(function (checkbox) {
return !checkbox.checked;
});
if (allUnchecked) {
areaCheckbox.checked = false;
toggleChildDevices(false);
} else {
areaCheckbox.checked = true;
toggleChildDevices(true);
}
});
});
});
});
</script>
2023-08-21 03:28:58 +00:00
<script>
function combineDateTime(dateString, timeString) {
const date = new Date(dateString);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
// Разбиение времени на часы, минуты и секунды
const timeParts = timeString.split(":");
const hours = timeParts[0].padStart(2, "0");
const minutes = timeParts[1].padStart(2, "0");
const seconds = timeParts[2].padStart(2, "0");
// Собираем дату и время в нужном формате
const combinedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
return combinedDateTime;
}
2023-08-28 11:25:45 +00:00
let HasData;
let recordID;
var selectedChannel = 1;
async function sendPostRequest() {
2023-09-17 12:22:14 +00:00
updateCameraOptions();
document.getElementById("dataLoading").style.display = 'flex';
2023-08-21 03:28:58 +00:00
// Получение данных из полей ввода
const selectedDate = document.getElementById("selectedDate").value;
const videoTime = document.getElementById("video-time").value;
2023-08-28 11:25:45 +00:00
const videoEndTime = document.getElementById("video-end-time").value;
2023-08-21 03:28:58 +00:00
const selectedSerial = document.querySelector('input[name="camera-serial"]:checked').value;
2023-08-28 11:25:45 +00:00
2023-08-21 03:28:58 +00:00
// Объединяем дату и время и преобразуем в нужный формат
const combinedDateTime = combineDateTime(selectedDate, videoTime);
2023-08-28 11:25:45 +00:00
const response = await fetch(`/getData?serial=${selectedSerial}&selectedDate=${formatDate(selectedDate)}&selectedTime=${formatTime(videoTime)}&selectedChannel=${selectedChannel}`);
const data = await response.json();
HasData = data.success;
2023-08-28 11:25:45 +00:00
if (data.success) {
console.log(`Данные доступны. DATAID: ${data.dataId}`)
recordID = data.dataId;
const requestData = {
serial: selectedSerial,
datetime: combinedDateTime,
};
2023-08-28 11:25:45 +00:00
fetch("/getspeedarchive", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(requestData),
})
.then((response) => response.json())
.then((data) => {
const existingChart = Chart.getChart("speed");
if (existingChart) {
existingChart.destroy();
}
const numberOfLabels = data.speeds.length;
2023-09-17 12:22:14 +00:00
// const labels = Array.from({ length: numberOfLabels }, () => "");
2023-08-28 11:25:45 +00:00
// Обновление данных графика
const chart = new Chart("speed", {
type: "line",
data: {
2023-09-17 12:22:14 +00:00
labels: data.names,
2023-08-28 11:25:45 +00:00
datasets: [
{
label: "Скорость",
borderColor: "#8086F9",
fill: false,
data: data.speeds,
pointStyle: false,
pointRadius: 25,
pointHoverRadius: 25,
tension: 0.1,
},
],
},
options: {
plugins: {
legend: {
display: false,
},
},
labelStep: "3",
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
stacked: true,
grid: {
display: true,
color: "#D9D9D9",
},
ticks: {
stepSize: 10,
},
},
x: {
2023-09-17 12:22:14 +00:00
ticks: {
autoSkip: false,
callback: function(value, index, values) {
const data = this.chart.data.labels;
if (index === 0 || index === values.length - 1) {
return data[index];
} else {
return '';
}
},
position: 'bottom',
maxRotation: 0,
},
2023-08-28 11:25:45 +00:00
grid: {
display: false,
},
},
},
},
});
const geoData = data.geo;
// Очищаем все слои на карте
map.eachLayer(layer => {
if (layer !== map) {
map.removeLayer(layer);
}
});
// Добавляем слой с плитками OpenStreetMap
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}').addTo(map);
// Создаем слой для маршрута
const routeLayer = L.layerGroup().addTo(map);
// Создаем слой для маркеров
const markerLayer = L.layerGroup().addTo(map);
// Преобразуем координаты точек маршрута
const routePoints = geoData.map(point => [point.latitude, point.longitude]);
// Создаем линию маршрута
const route = L.polyline(routePoints, { color: 'red',weight: 5 }).addTo(routeLayer);
})
.catch((error) => {
2023-09-17 12:22:14 +00:00
document.getElementById("dataLoading").style.display = 'none';
var h1Element = document.querySelector('.speedometr h1');
h1Element.textContent = 'Ошибка отправки запроса.';
2023-08-28 11:25:45 +00:00
console.error("Ошибка при отправке запроса:", error);
});
const endResponse = await fetch(`/getData?serial=${selectedSerial}&selectedDate=${formatDate(selectedDate)}&selectedTime=${formatTime(videoEndTime)}&selectedChannel=${selectedChannel}`);
const endData = await endResponse.json();
if (endData.success) {
2023-09-17 12:22:14 +00:00
document.getElementById("dataLoading").style.display = 'none';
2023-08-28 11:25:45 +00:00
console.log(`Конечные данные доступны. DATAID: ${endData.dataId}`)
const speedBG = document.getElementById("speed-bg");
speedBG.style.display = 'none';
HasData = true;
if (data.dataId != endData.dataId) {
2023-09-17 12:22:14 +00:00
const existingChart = Chart.getChart("speed");
if (existingChart) {
existingChart.destroy();
}
const chart = new Chart("speed", {
type: "line",
data: {
labels: "",
datasets: [
{
label: "Скорость",
borderColor: "#8086F9",
fill: false,
data: "",
pointStyle: false,
pointRadius: 25,
pointHoverRadius: 25,
tension: 0.1,
},
],
},
options: {
plugins: {
legend: {
display: false,
},
},
labelStep: "3",
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
stacked: true,
grid: {
display: true,
color: "#D9D9D9",
},
ticks: {
stepSize: 10,
},
},
x: {
grid: {
display: false,
},
},
},
},
});
2023-08-28 11:25:45 +00:00
HasData = false;
var h1Element = document.querySelector('.speedometr h1');
h1Element.textContent = 'Временной диапазон находится в разных видео сессиях. Измените время.';
const speedBG = document.getElementById("speed-bg");
speedBG.style.display = 'flex';
}
} else {
2023-09-17 12:22:14 +00:00
document.getElementById("dataLoading").style.display = 'none';
const existingChart = Chart.getChart("speed");
if (existingChart) {
existingChart.destroy();
}
const chart = new Chart("speed", {
type: "line",
data: {
labels: "",
datasets: [
{
label: "Скорость",
borderColor: "#8086F9",
fill: false,
data: "",
pointStyle: false,
pointRadius: 25,
pointHoverRadius: 25,
tension: 0.1,
},
],
},
options: {
plugins: {
legend: {
display: false,
},
},
labelStep: "3",
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
stacked: true,
grid: {
display: true,
color: "#D9D9D9",
},
ticks: {
stepSize: 10,
},
},
x: {
grid: {
display: false,
},
},
},
},
});
2023-08-28 11:25:45 +00:00
HasData = false;
const speedBG = document.getElementById("speed-bg");
speedBG.style.display = 'flex';
var h1Element = document.querySelector('.speedometr h1');
h1Element.textContent = 'Данных для выбранного периода нет.';
}
} else {
2023-09-17 12:22:14 +00:00
const existingChart = Chart.getChart("speed");
if (existingChart) {
existingChart.destroy();
}
const chart = new Chart("speed", {
type: "line",
data: {
labels: "",
datasets: [
{
label: "Скорость",
borderColor: "#8086F9",
fill: false,
data: "",
pointStyle: false,
pointRadius: 25,
pointHoverRadius: 25,
tension: 0.1,
},
],
},
options: {
plugins: {
legend: {
display: false,
},
},
labelStep: "3",
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
stacked: true,
grid: {
display: true,
color: "#D9D9D9",
},
ticks: {
stepSize: 10,
},
},
x: {
grid: {
display: false,
},
},
},
},
});
2023-08-28 11:25:45 +00:00
var h1Element = document.querySelector('.speedometr h1');
h1Element.textContent = 'Данных для выбранного периода нет.';
const speedBG = document.getElementById("speed-bg");
speedBG.style.display = 'flex';
}
2023-08-21 03:28:58 +00:00
2023-08-28 11:25:45 +00:00
2023-08-21 03:28:58 +00:00
}
const radioInputs = document.querySelectorAll(".radio-input");
radioInputs.forEach((input) => {
input.addEventListener("change", sendPostRequest);
});
const selectedDateInput = document.getElementById("selectedDate");
selectedDateInput.addEventListener("change", sendPostRequest);
const videoTimeInput = document.getElementById("video-time");
2023-09-17 12:22:14 +00:00
videoTimeInput.addEventListener("blur", sendPostRequest);
2023-08-21 03:28:58 +00:00
2023-08-28 11:25:45 +00:00
const endVideoTimeInput = document.getElementById("video-end-time");
2023-09-17 12:22:14 +00:00
endVideoTimeInput.addEventListener("blur", sendPostRequest);
2023-08-28 11:25:45 +00:00
2023-08-21 03:28:58 +00:00
</script>
<script>
var now = new Date();
now.setHours(now.getHours() - 1);
var formattedTime = now.toISOString().substr(11, 8);
document.getElementById("video-time").value = formattedTime;
2023-08-28 11:25:45 +00:00
const startTimeInput = document.getElementById('video-time');
const endTimeInput = document.getElementById('video-end-time');
const startTime = new Date(`1970-01-01T${startTimeInput.value}Z`);
startTime.setHours(startTime.getHours() - 3);
startTime.setSeconds(startTime.getSeconds() + 10);
const hours = startTime.getHours().toString().padStart(2, '0');
const minutes = startTime.getMinutes().toString().padStart(2, '0');
const seconds = startTime.getSeconds().toString().padStart(2, '0');
const endTimeString = `${hours}:${minutes}:${seconds}`;
endTimeInput.value = endTimeString;
2023-08-21 03:28:58 +00:00
</script>
<script>
document.addEventListener("DOMContentLoaded", function () {
const prevMonthBtn = document.getElementById("prevMonth");
const nextMonthBtn = document.getElementById("nextMonth");
const monthYear = document.getElementById("monthYear");
const datesContainer = document.getElementById("dates");
const dateForm = document.getElementById("dateForm");
const selectedDateInput = document.getElementById("selectedDate");
let currentDate = new Date();
let selectedDate = currentDate;
selectedDateInput.value = selectedDate.toISOString();
function renderCalendar() {
// Очистить предыдущий календарь
datesContainer.innerHTML = "";
// Установить заголовок с месяцем и годом
const options = { year: "numeric", month: "long" };
const formattedDate = currentDate.toLocaleDateString("ru-RU", options);
const formattedMonthYear = formattedDate.charAt(0).toUpperCase() + formattedDate.slice(1);
monthYear.textContent = formattedMonthYear.replace('г.', '');
// Найти первый день текущего месяца
const firstDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
// Определить день недели, с которого начнется месяц
const startingDay = firstDayOfMonth.getDay() - 1;
// Определить количество дней в текущем месяце
const daysInMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0).getDate();
// Создать дни месяца
for (let i = 0; i < startingDay; i++) {
const emptyDay = document.createElement("div");
emptyDay.classList.add("empty-day");
datesContainer.appendChild(emptyDay);
}
for (let day = 1; day <= daysInMonth; day++) {
const dateCell = document.createElement("div");
dateCell.textContent = day;
dateCell.classList.add("date");
if (selectedDate.getDate() === day && selectedDate.getMonth() === currentDate.getMonth() && selectedDate.getFullYear() === currentDate.getFullYear()) {
dateCell.classList.add("selected");
}
dateCell.addEventListener("click", () => {
selectedDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), day);
renderCalendar();
selectedDateInput.value = selectedDate.toISOString();
2023-08-28 11:25:45 +00:00
sendPostRequest();
2023-08-21 03:28:58 +00:00
});
datesContainer.appendChild(dateCell);
}
2023-08-28 11:25:45 +00:00
2023-08-21 03:28:58 +00:00
}
// Перейти на предыдущий месяц
prevMonthBtn.addEventListener("click", () => {
currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1);
renderCalendar();
});
// Перейти на следующий месяц
nextMonthBtn.addEventListener("click", () => {
currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1);
renderCalendar();
});
// Инициализировать календарь
renderCalendar();
});
</script>
2023-08-28 04:40:58 +00:00
<script>
2023-08-28 11:25:45 +00:00
function formatDate(selectedDate) {
2023-08-28 04:40:58 +00:00
const date = new Date(selectedDate);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}${month}${day}`;
}
2023-08-21 03:28:58 +00:00
2023-08-28 04:40:58 +00:00
function formatTime(videoTime) {
const parts = videoTime.split(':');
const hours = parts[0].toString().padStart(2, '0');
const minutes = parts[1].toString().padStart(2, '0');
const seconds = parts[2].toString().padStart(2, '0');
return `${hours}${minutes}${seconds}`;
}
2023-08-21 03:28:58 +00:00
2023-09-17 12:22:14 +00:00
async function playVideo() {
const channel = document.getElementById("group-id").value;
2023-08-28 04:40:58 +00:00
const selectedDevice = document.querySelector('input[name="camera-serial"]:checked');
if (!selectedDevice) {
alert('Пожалуйста, выберите устройство из списка.');
return;
}
2023-09-17 12:22:14 +00:00
if (channel === "") {
alert('Пожалуйста, выберите камеру из списка.');
return;
}
2023-08-28 11:25:45 +00:00
if (!HasData) {
alert('Пожалуйста, выберите другой временной период.');
return;
}
if (videoTimeInput.value > endVideoTimeInput.value) {
alert('Конечное время не может быть больше начального.');
return;
}
2023-09-17 12:22:14 +00:00
document.getElementById("exportLoading").style.display = 'flex';
2023-08-21 03:28:58 +00:00
2023-08-28 04:40:58 +00:00
const startTimeInput = document.getElementById('video-time');
2023-08-28 11:25:45 +00:00
const endTimeInput = document.getElementById('video-end-time');
2023-08-28 04:40:58 +00:00
const selectedDateInput = document.getElementById('selectedDate');
const startTime = formatTime(startTimeInput.value);
2023-08-28 11:25:45 +00:00
const endTime = formatTime(endTimeInput.value);
2023-08-28 04:40:58 +00:00
const selectedDate = formatDate(selectedDateInput.value);
2023-08-21 03:28:58 +00:00
2023-08-28 11:25:45 +00:00
const reqDate = document.getElementById("selectedDate").value;
const reqTime = document.getElementById("video-time").value;
const reqSerial = document.querySelector('input[name="camera-serial"]:checked').value;
const finalResponse = await fetch(`/getData?serial=${reqSerial}&selectedDate=${formatDate(reqDate)}&selectedTime=${formatTime(reqTime)}&selectedChannel=${channel}`);
2023-08-28 11:25:45 +00:00
const resData = await finalResponse.json();
2023-08-21 03:28:58 +00:00
2023-08-28 04:40:58 +00:00
const serial = selectedDevice.value;
2023-08-21 03:28:58 +00:00
const url = `http://localhost:8081/export?url=http%3A%2F%2F{{SERVER_IP}}%3A8080%2Fhttp%2Fdownload.flv%3Fserial%3D${serial}%26channel%3D${channel}%26queryTime%3D${selectedDate}%26startTime%3D${startTime}%26endTime%3D${endTime}%26recordID%3D${resData.dataId}`;
document.getElementById("exportLoading").style.display = 'none';
2023-08-28 11:25:45 +00:00
window.open(url, '_blank');
2023-08-28 04:40:58 +00:00
}
</script>
2023-08-21 03:28:58 +00:00
2023-08-21 03:52:58 +00:00
2023-08-28 04:40:58 +00:00
2023-08-21 03:28:58 +00:00
<script>
window.addEventListener('DOMContentLoaded', function() {
var mapContainer = document.querySelector('.map');
var mapArea = document.getElementById('map');
mapArea.style.height = (mapContainer.clientHeight) + 'px';
mapArea.style.width = (mapContainer.clientWidth) + 'px';
});
window.addEventListener("resize", function (event) {
var mapContainer = document.querySelector('.map');
var mapArea = document.getElementById('map');
mapArea.style.height = (mapContainer.clientHeight) + 'px';
mapArea.style.width = (mapContainer.clientWidth) + 'px';
});
2023-08-22 15:29:23 +00:00
var startPoint = [0, 0];
var endPoint = [0, 0];
2023-08-21 03:28:58 +00:00
2023-08-22 15:29:23 +00:00
let map;
2023-08-21 03:28:58 +00:00
2023-08-22 15:29:23 +00:00
// Создаем карту Leaflet
map = L.map('map').setView([59.855198, 30.282995], 10);
2023-08-21 03:28:58 +00:00
2023-08-22 15:29:23 +00:00
// Добавляем базовый слой OpenStreetMap
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}').addTo(map);
2023-08-21 03:28:58 +00:00
2023-08-22 15:29:23 +00:00
// Создаем маркеры
var startMarker = L.marker(startPoint, {
icon: L.divIcon({
className: 'custom-icon',
html: '<div style="background-color: red; width: 14px; height: 14px; border: 2px solid white; border-radius: 50%;"></div>'
})
}).addTo(map);
2023-08-21 03:28:58 +00:00
2023-08-22 15:29:23 +00:00
var endMarker = L.marker(endPoint, {
icon: L.divIcon({
className: 'custom-icon',
html: '<div style="background-color: red; width: 14px; height: 14px; border: 2px solid white; border-radius: 50%;"></div>'
})
}).addTo(map);
2023-08-21 03:28:58 +00:00
2023-08-22 15:29:23 +00:00
// Создаем линию маршрута
var route = L.polyline([startPoint, endPoint], { color: 'red', weight: 6 }).addTo(map);
2023-08-21 03:28:58 +00:00
2023-08-22 15:29:23 +00:00
// Скрыть кнопки приближения/отдаления
map.zoomControl.remove();
2023-08-21 03:28:58 +00:00
2023-08-22 15:29:23 +00:00
// Скрыть информационную панель
map.attributionControl.remove();
2023-08-21 03:28:58 +00:00
</script>
<script>
// Скрытие/Показ дополнительных меню аккаунта
const accountMain = document.getElementById('account-main');
const accountAdditional = document.getElementById('account-additional');
const accountUp = document.getElementById('up');
const accountDown = document.getElementById('down');
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountMain.addEventListener('click', () => {
if (accountAdditional.style.display === 'none') {
accountAdditional.style.display = 'flex';
accountUp.style.display = 'unset';
accountDown.style.display = 'none';
} else {
accountAdditional.style.display = 'none';
accountUp.style.display = 'none';
accountDown.style.display = 'unset';
}
});
</script>
<script>
Chart.defaults.color = "rgba(0, 0, 0, 0.4)";
Chart.defaults.font.size = 15;
Chart.defaults.font.weight = 400;
var speedData = {
labels: [
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
],
datasets: [
{
label: "Скорость",
borderColor: "#8086F9",
fill: false,
2023-09-17 12:22:14 +00:00
data: "",
2023-08-21 03:28:58 +00:00
pointStyle: false,
pointRadius: 25,
pointHoverRadius: 25,
tension: 0.1,
},
],
};
var speedOptions = {
plugins: {
legend: {
display: false,
},
},
labelStep: "3",
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
stacked: true,
grid: {
display: true,
color: "#D9D9D9",
},
ticks: {
stepSize: 10,
},
},
x: {
grid: {
display: false,
},
},
},
};
new Chart("speed", {
type: "line",
data: speedData,
options: speedOptions,
});
</script>
</body>
</html>