parameters update, pdf fix, server-ip added

This commit is contained in:
Ivan 2023-09-21 08:54:26 +03:00
parent 8f3944692f
commit fde77bfb47
Signed by untrusted user who does not match committer: ppechenkoo
GPG Key ID: 0C191B86D9582583
8 changed files with 550 additions and 276 deletions

337
server.js
View File

@ -7,7 +7,6 @@ const handlebars = require("handlebars");
require("dotenv").config(); require("dotenv").config();
const multer = require("multer"); const multer = require("multer");
const http = require("http"); const http = require("http");
const Client = require('ssh2').Client;
const axios = require('axios'); const axios = require('axios');
const moment = require('moment'); const moment = require('moment');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
@ -55,17 +54,6 @@ app.get("/settings", settings);
app.get("/admin", adminPanel); app.get("/admin", adminPanel);
app.get("/admin/organisation", organisation); app.get("/admin/organisation", organisation);
const connectionProperties = {
host: process.env.SSH_HOST,
port: process.env.SSH_PORT,
username: process.env.SSH_USERNAME,
password: process.env.SSH_PASSWORD,
};
const commandToExecute = 'docker ps | grep connectionserver-video-server';
const conn = new Client();
async function getUserInfo(userId) { async function getUserInfo(userId) {
const pool = new Pool({ const pool = new Pool({
user: DB_User, user: DB_User,
@ -131,53 +119,23 @@ app.post("/videos/restart", async (req, res) => {
if (req.session.userId === undefined) { if (req.session.userId === undefined) {
return res.redirect("/signin"); return res.redirect("/signin");
} }
conn.on('ready', function() {
console.log('Подключение по SSH успешно'); var options = {
method: 'GET',
url: `http://${process.env.SERVER_IP}:8080/http/restart`,
headers: {'Content-Type': 'application/json'},
data: {video: true}
};
conn.exec(commandToExecute, function(err, stream) { axios.request(options).then(function (response) {
if (err) throw err; res.status(200).json({ message: "Команда для рестарта выполнена." });
return;
let containerId = ''; }).catch(function (error) {
console.error(error);
stream res.status(500).json({ error: "Ошибка сервера" });
.on('data', function(data) { return;
const lines = data.toString().split('\n');
for (const line of lines) {
if (line.includes('connectionserver-video-server')) {
containerId = line.trim().split(/\s+/)[0];
break;
}
}
if (containerId) {
console.log('Найден CONTAINER ID:', containerId);
const restartCommand = `docker restart ${containerId}`;
conn.exec(restartCommand, function(err, stream) {
if (err);
console.log('Команда для рестарта выполнена.');
conn.end(); // Закрываем соединение SSH
res.status(200).json({ message: "Команда для рестарта выполнена." });
return;
});
} else {
console.log('Контейнер connectionserver-video-server не найден.');
conn.end(); // Закрываем соединение SSH
}
})
.stderr.on('data', function(data) {
console.error('Ошибка выполнения команды:', data.toString());
conn.end(); // Закрываем соединение SSH
res.status(500).json({ error: "Ошибка сервера" });
return;
});
}); });
}).connect(connectionProperties);
conn.on('error', function(err) {
console.error('Ошибка подключения: ' + err.message);
});
}); });
@ -199,6 +157,7 @@ async function index(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
var templateData = { var templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -517,6 +476,7 @@ async function live(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -827,7 +787,7 @@ app.post("/devices-geo", async (req, res) => {
INNER JOIN registrars r ON g.serial = r.serial INNER JOIN registrars r ON g.serial = r.serial
`; `;
pool.query(subquery, selectedDevices, (err, result) => { pool.query(subquery, selectedDevices, async (err, result) => {
if (err) { if (err) {
console.error("Ошибка выполнения запроса:", err); console.error("Ошибка выполнения запроса:", err);
res.status(500).json({ error: "Ошибка сервера" }); res.status(500).json({ error: "Ошибка сервера" });
@ -836,12 +796,16 @@ pool.query(subquery, selectedDevices, (err, result) => {
const minuteInMillis = 60000; const minuteInMillis = 60000;
const devicesData = result.rows.map((row) => { const devicesData = [];
for (const row of result.rows) {
if (row.speed > 150) { if (row.speed > 150) {
row.speed /= 100; row.speed /= 100;
} }
return { const groupName = await getGroupNameById(pool, row.group);
const deviceData = {
serial: row.serial, serial: row.serial,
longitude: row.longitude, longitude: row.longitude,
latitude: row.latitude, latitude: row.latitude,
@ -851,15 +815,26 @@ pool.query(subquery, selectedDevices, (err, result) => {
number: row.number, number: row.number,
plate: row.plate, plate: row.plate,
group: row.group, group: row.group,
groupName: groupName,
}; };
});
// console.log(devicesData) devicesData.push(deviceData);
}
res.json({ devicesData }); res.json({ devicesData });
}); });
}); });
async function getGroupNameById(pool, groupId) {
const query = "SELECT name FROM groups WHERE id = $1";
const result = await pool.query(query, [groupId]);
if (result.rows.length > 0) {
return result.rows[0].name;
}
return 'Другое';
}
async function reports(req, res) { async function reports(req, res) {
if (req.session.userId === undefined) { if (req.session.userId === undefined) {
@ -867,6 +842,7 @@ async function reports(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -1215,36 +1191,6 @@ app.get("/api/devices", async (req, res) => {
} }
}); });
async function generatePDF(data) {
const browser = await puppeteer.launch({
headless: true,
ignoreDefaultArgs: ['--disable-extensions']
}); const page = await browser.newPage();
const htmlTemplate = fs.readFileSync('static/templates/reports/pdf.html', 'utf-8');
const filledTemplate = htmlTemplate
.replace(/{{Id}}/g, data.Id)
.replace(/{{Organisation}}/g, data.Organisation)
.replace(/{{Type}}/g, data.Type)
.replace(/{{Speed}}/g, data.Speed)
.replace(/{{Date}}/g, data.Date)
.replace(/{{Serial}}/g, data.Serial)
.replace(/{{Geo}}/g, data.Geo)
.replace(/{{PrevLongitude}}/g, data.PrevLongitude)
.replace(/{{PrevLatitude}}/g, data.PrevLatitude)
.replace(/{{NextLongitude}}/g, data.NextLongitude)
.replace(/{{NextLatitude}}/g, data.NextLatitude)
.replace(/{{Speeds}}/g, data.Speeds);
await page.setContent(filledTemplate);
await new Promise(resolve => setTimeout(resolve, 1000));
await page.pdf({ path: 'report.pdf', format: 'A4' });
await browser.close();
}
@ -1256,6 +1202,7 @@ app.get('/reports/:id', async (req, res) => {
const id = req.params.id; const id = req.params.id;
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -1568,6 +1515,7 @@ app.get('/generate-pdf/:id', async (req, res) => {
const id = req.params.id; const id = req.params.id;
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -1814,19 +1762,22 @@ let data = {
Speeds: templateData.Speeds, Speeds: templateData.Speeds,
}; };
generatePDF(data) const source = fs.readFileSync("static/templates/reports/pdf.html", "utf8");
.then(() => { const template = handlebars.compile(source);
console.log('PDF создан успешно.'); const resultT = template(templateData);
res.sendFile(`${__dirname}/report.pdf`); res.send(resultT);
}) } catch (error) {
.catch((error) => { console.error(error);
console.error('Ошибка при создании PDF:', error); templateData.ifDBError = true;
res.status(500).send('Ошибка при создании PDF');
}); const source = fs.readFileSync(
} catch (error) { "static/templates/reports/pdf.html",
console.error(error); "utf8"
res.status(500).send('Ошибка при получении данных'); );
} const template = handlebars.compile(source);
const resultT = template(data);
res.send(resultT);
}
}); });
@ -1837,6 +1788,7 @@ async function devices(req, res) {
let userInfo; let userInfo;
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: '', Organisation: '',
User: '', User: '',
UserInfo: '', UserInfo: '',
@ -1906,6 +1858,7 @@ async function devices(req, res) {
userInfo = await getUserInfo(req.session.userId); userInfo = await getUserInfo(req.session.userId);
templateData = { templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -1934,7 +1887,6 @@ async function devices(req, res) {
GroupsList: groupsResult.rows, GroupsList: groupsResult.rows,
}; };
console.log(templateData.Groups);
const source = fs.readFileSync("static/templates/devices/index.html", "utf8"); const source = fs.readFileSync("static/templates/devices/index.html", "utf8");
const template = handlebars.compile(source); const template = handlebars.compile(source);
@ -1969,6 +1921,7 @@ async function groups(req, res) {
return res.redirect("/signin"); return res.redirect("/signin");
} }
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
ifDBError: false, ifDBError: false,
@ -2041,29 +1994,70 @@ app.post('/update-group', async (req, res) => {
} }
}); });
async function getParameterByName(serial, fieldName) { async function getParameters(serial) {
const requestPayload = {
FIELDS: [fieldName],
};
const requestResponse = await axios.get(`http://krbl.ru:8080/http/parameters/request?serial=${serial}`, { const requestResponse = await axios.get(`http://${process.env.SERVER_IP}:8080/http/parameters/request?serial=${serial}`, {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
data: JSON.stringify(requestPayload), data: JSON.stringify({
"FIELDS": [
"DOSD"
]
}),
}); });
const requestResponse2 = await axios.get(`http://${process.env.SERVER_IP}:8080/http/parameters/request?serial=${serial}`, {
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
"FIELDS": [
"GSP"
]
}),
});
const requestResponse3 = await axios.get(`http://${process.env.SERVER_IP}:8080/http/parameters/request?serial=${serial}`, {
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
"FIELDS": [
"TIMEP"
]
}),
});
const requestResponse4 = await axios.get(`http://${process.env.SERVER_IP}:8080/http/parameters/request?serial=${serial}`, {
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
"FIELDS": [
"SUBSTRNET"
]
}),
});
const requestResponse5 = await axios.get(`http://${process.env.SERVER_IP}:8080/http/parameters/request?serial=${serial}`, {
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
"FIELDS": [
"AR"
]
}),
});
// console.log(requestResponse.data); // console.log(requestResponse.data);
await new Promise(resolve => setTimeout(resolve, 300)); await new Promise(resolve => setTimeout(resolve, 300));
const getResponse = await axios.get(`http://krbl.ru:8080/http/parameters/get?serial=${serial}`); const getResponse = await axios.get(`http://${process.env.SERVER_IP}:8080/http/parameters/get?serial=${serial}`);
// console.log(getResponse.data); // console.log(getResponse.data);
const fieldPath = findPathForField(fieldName); return getResponse.data;
if (fieldPath) {
const value = _.get(getResponse.data, fieldPath);
return { [fieldName]: value };
}
return null;
} }
app.post('/device-parameters', async (req, res) => { app.post('/device-parameters', async (req, res) => {
@ -2071,20 +2065,12 @@ app.post('/device-parameters', async (req, res) => {
return res.redirect("/signin"); return res.redirect("/signin");
} }
try { try {
const { serial, FIELDS } = req.body; const { serial } = req.body;
// console.log(serial, FIELDS);
const responseData = {};
// Используем асинхронный цикл для выполнения GET-запросов по очереди // Используем асинхронный цикл для выполнения GET-запросов по очереди
for (const field of FIELDS) { const responseData = await getParameters(serial);
const parameter = await getParameterByName(serial, field);
if (parameter) {
Object.assign(responseData, parameter);
}
}
// console.log(responseData);
res.json(responseData); res.json(responseData);
} catch (error) { } catch (error) {
@ -2093,27 +2079,6 @@ app.post('/device-parameters', async (req, res) => {
} }
}); });
function findPathForField(fieldName) {
const fieldPathMap = {
"VEHICLEID": "DATA.RIP.BN",
"DATEMOD": "DATA.TIMEP.DATEM",
"TIMEFORMAT": "DATA.TIMEP.TIMEM",
"LANGUAGE": "DATA.GSP.LANT",
"VIDEOFORMAT": "DATA.GSP.VGA",
"GEOMOD": "DATA.GSP.GM",
"SUBSTREAMMODE": "DATA.SUBSTRNET.SM",
"NETWORK": "DATA.SUBSTRNET.NEC",
"DISPLAYMENU": "DATA.DOSD",
"RECORDINGPARAMS": "DATA.RP.RCP",
"FUTURERECORDINGSTYLE": "DATA.MP.OT",
"FUTURERECORDING": "DATA.MP.OT",
"STREAMPARAMS": "DATA.AR.VEC",
"VIDEOIMAGEMOD": "DATA.SVIP",
};
return fieldPathMap[fieldName] || null;
}
app.put('/device-parameters', async (req, res) => { app.put('/device-parameters', async (req, res) => {
if (req.session.userId === undefined) { if (req.session.userId === undefined) {
return res.redirect("/signin"); return res.redirect("/signin");
@ -2130,6 +2095,7 @@ app.put('/device-parameters', async (req, res) => {
VIDEOFORMAT, VIDEOFORMAT,
GEOMOD, GEOMOD,
SUBSTREAMMODE, SUBSTREAMMODE,
TIMEZ,
NE, NE,
TE, TE,
VE, VE,
@ -2139,30 +2105,60 @@ app.put('/device-parameters', async (req, res) => {
// Создаем JSON для GET запроса // Создаем JSON для GET запроса
const requestBody = { const requestBody = {
TIMEP: { "TIMEP": {
DATEM: parseInt(DATEMOD, 10) || 1, "DATEM": parseInt(DATEMOD, 10) || 1,
TIMEM: parseInt(TIMEFORMAT, 10) || 0 "TIMEM": parseInt(TIMEFORMAT, 10) || 0,
"TIMEZ": TIMEZ || "180C"
}, },
GSP: { "GSP": {
LANT: parseInt(LANGUAGE, 10) || 12, "LANT": parseInt(LANGUAGE, 10) || 12,
VGA: parseInt(VIDEOFORMAT, 10) || 0, "VGA": parseInt(VIDEOFORMAT, 10) || 0,
GM: parseInt(GEOMOD, 10) || 0 "GM": parseInt(GEOMOD, 10) || 0
}, },
SUBSTRNET: { "SUBSTRNET": {
SM: parseInt(SUBSTREAMMODE, 10) || 1 "SM": parseInt(SUBSTREAMMODE, 10) || 1
}, },
DOSD: { "DOSD": {
NE: parseInt(NE, 10) || 1, "NE": parseInt(NE, 10) || 1,
TE: parseInt(TE, 10) || 1, "TE": parseInt(TE, 10) || 1,
VE: parseInt(VE, 10) || 0, "VE": parseInt(VE, 10) || 0,
SE: parseInt(SE, 10) || 0, "SE": parseInt(SE, 10) || 0,
GE: parseInt(GE, 10) || 0 "GE": parseInt(GE, 10) || 0
} }
}; };
// Отправляем GET запрос с JSON BODY
try {
const response = await axios.get(`http://${process.env.SERVER_IP}:8080/http/parameters/set?serial=${serial}`, {
data: JSON.stringify(requestBody),
headers: {
'Content-Type': 'application/json'
}
});
res.status(response.status).send(response.data);
} catch (error) {
res.status(500).send('Произошла ошибка при отправке GET запроса.');
}
});
app.put('/camera-parameters', async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
// Получаем данные из PUT запроса
const camerasData = req.body;
const { serial } = req.query;
// Создаем JSON для GET запроса
const requestBody = {
"AR": camerasData
};
// Отправляем GET запрос с JSON BODY // Отправляем GET запрос с JSON BODY
try { try {
const response = await axios.get(`http://krbl.ru:8080/http/parameters/set?serial=${serial}`, { const response = await axios.get(`http://${process.env.SERVER_IP}:8080/http/parameters/set?serial=${serial}`, {
data: JSON.stringify(requestBody), data: JSON.stringify(requestBody),
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@ -2691,6 +2687,7 @@ async function drivers(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -2773,6 +2770,7 @@ async function update(req, res) {
return res.redirect("/signin"); return res.redirect("/signin");
} }
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
ifDBError: false, ifDBError: false,
@ -2808,6 +2806,7 @@ async function settings(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
ifDBError: false, ifDBError: false,
@ -2843,6 +2842,7 @@ async function organisation(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
ifDBError: false, ifDBError: false,
@ -2909,6 +2909,7 @@ async function adminPanel(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
ifDBError: false, ifDBError: false,
@ -3025,6 +3026,7 @@ app.get('/admin/user/:id', async (req, res) => {
const id = req.params.id; const id = req.params.id;
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -3115,7 +3117,6 @@ templateData.Groups = Object.keys(groupedRegistrars).map((groupName) => ({
numbers: groupedNumbers[groupName], numbers: groupedNumbers[groupName],
})); }));
console.log(templateData.Groups);
const source = fs.readFileSync("static/templates/admin/user.html", "utf8"); const source = fs.readFileSync("static/templates/admin/user.html", "utf8");
const template = handlebars.compile(source); const template = handlebars.compile(source);
@ -3218,6 +3219,7 @@ async function videos(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -3335,6 +3337,7 @@ async function videoExport(req, res) {
} }
const userInfo = await getUserInfo(req.session.userId); const userInfo = await getUserInfo(req.session.userId);
let templateData = { let templateData = {
SERVER_IP: process.env.SERVER_IP,
Organisation: userInfo.Organisation, Organisation: userInfo.Organisation,
User: userInfo.User, User: userInfo.User,
UserInfo: userInfo.Users, UserInfo: userInfo.Users,
@ -3455,10 +3458,10 @@ app.get('/getData', async (req, res) => {
const selectedChannel = req.query.selectedChannel; const selectedChannel = req.query.selectedChannel;
try { try {
const successResponse = await axios.get(`http://krbl.ru:8080/http/filelist/request?serial=${selectedSerial}&querytime=${selectedDate}&channel=${selectedChannel}`); const successResponse = await axios.get(`http://${process.env.SERVER_IP}:8080/http/filelist/request?serial=${selectedSerial}&querytime=${selectedDate}&channel=${selectedChannel}`);
if (successResponse.data.SUCCESS) { if (successResponse.data.SUCCESS) {
await new Promise(resolve => setTimeout(resolve, 7000)); await new Promise(resolve => setTimeout(resolve, 7000));
const dataResponse = await axios.get(`http://krbl.ru:8080/http/filelist/get?serial=${selectedSerial}&querytime=${selectedDate}&channel=${selectedChannel}`); const dataResponse = await axios.get(`http://${process.env.SERVER_IP}:8080/http/filelist/get?serial=${selectedSerial}&querytime=${selectedDate}&channel=${selectedChannel}`);
if (successResponse.data.SUCCESS) { if (successResponse.data.SUCCESS) {
const dataId = dataResponse.data.DATAID; const dataId = dataResponse.data.DATAID;
const dateRanges = dataResponse.data.DATA; const dateRanges = dataResponse.data.DATA;

View File

@ -14,6 +14,7 @@ const content2 = document.getElementById("sim");
const content3 = document.getElementById("ts"); const content3 = document.getElementById("ts");
const content4 = document.getElementById("equipment"); const content4 = document.getElementById("equipment");
const content5 = document.getElementById("parameters"); const content5 = document.getElementById("parameters");
const content6 = document.getElementById("cameras");
const btn1 = document.getElementById("continue-details"); const btn1 = document.getElementById("continue-details");
const btn2 = document.getElementById("continue-sim"); const btn2 = document.getElementById("continue-sim");
const btn3 = document.getElementById("continue-ts"); const btn3 = document.getElementById("continue-ts");
@ -106,6 +107,8 @@ for (let radioButton of radioButtons) {
switchContent(content4); switchContent(content4);
} else if (radioButton.value === "parameters") { } else if (radioButton.value === "parameters") {
switchContent(content5); switchContent(content5);
} else if (radioButton.value === "cameras") {
switchContent(content6);
} }
}); });
} }

View File

@ -174,7 +174,9 @@
<div class="vertical-line"></div> <div class="vertical-line"></div>
<input name="newStage" type="radio" value="equipment" id="stage-equipment"><label for="stage-equipment">Оборудование</label> <input name="newStage" type="radio" value="equipment" id="stage-equipment"><label for="stage-equipment">Оборудование</label>
<br> <br>
<input name="newStage" type="radio" value="parameters" id="stage-parameters"><label style="margin-top: 115%;" for="stage-parameters">Системные настройки</label> <input name="newStage" type="radio" value="parameters" id="stage-parameters"><label style="margin-top: 90%;" for="stage-parameters" id="stage-parameters-label">Системные настройки</label>
<div class="vertical-line" id="between-parameters-and-cameras"></div>
<input name="newStage" type="radio" value="cameras" id="stage-cameras"><label for="stage-cameras" id="stage-cameras-label">Настройки камер</label>
</section> </section>
</section> </section>
<section id="add-new-container" class="add-new"> <section id="add-new-container" class="add-new">
@ -440,7 +442,23 @@
</form> </form>
<div id="parameters" class="new-parameters"> <div id="parameters" style="position: relative;" class="new-parameters">
<section style="display: flex; width: 100%; height:100%; top: 0; left: 0;" class="dberror" id="parameters-bg" >
<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>
<h1>Системные настройки</h1> <h1>Системные настройки</h1>
<h2>Параметры регистраторов</h2> <h2>Параметры регистраторов</h2>
@ -464,18 +482,19 @@
</select> </select>
</div> </div>
<div class="parameters-input"> <div class="parameters-input">
<label for="system-video">Формат видео</label> <label for="system-timezone">Часовой пояс</label>
<select name="VIDEOFORMAT" id="system-video"> <select name="TIMEZ" id="system-timezone">
<option value="0">800 x 600 px</option> <option value="120A">(МСК-1) Калининград</option>
<option value="1">1024 x 768 px</option> <option value="180C">(МСК) Москва</option>
<option value="2">1280 x 1024 px</option> <option value="240A">(МСК+1) Самара</option>
<option value="3">1366 x 768 px</option> <option value="300A">(МСК+2) Екатеринбург</option>
<option value="4">1440 x 900 px</option> <option value="360A">(МСК+3) Омск</option>
<option value="5">720p</option> <option value="420A">(МСК+4) Красноярск</option>
<option value="6">1080I</option> <option value="480A">(МСК+5) Иркутск</option>
<option value="7">1080p</option> <option value="540A">(МСК+6) Якутск</option>
<option value="8">480p</option> <option value="600A">(МСК+7) Владивосток</option>
<option value="9">576p</option> <option value="660A">(МСК+8) Магадан</option>
<option value="720A">(МСК+9) Камчатка</option>
</select> </select>
</div> </div>
<div class="parameters-input"> <div class="parameters-input">
@ -523,6 +542,117 @@
</div> </div>
<div id="cameras" style="position: relative;" class="new-parameters">
<section style="display: flex; width: 100%; height:100%; top: 0; left: 0;" class="dberror" id="cameras-bg" >
<div class="loader-container">
<div 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>
</div>
</section>
<h1>Настройки камер</h1>
<h2>Выберите нужную камеру и выставьте параметры</h2>
<div class="horizontal-line"></div>
<label style="width: 100%;" for="cameras-id">Номер камеры</label>
<select style="width: 100%;" name="cameras-id" id="cameras-id">
<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>
<option value="14">Камера 14</option>
<option value="15">Камера 15</option>
<option value="16">Камера 16</option>
</select>
<div class="horizontal-line"></div>
<div class="parameters-inputs">
<div class="parameters-input">
<label for="cameras-quality">Качество видео</label>
<select name="QLT" id="cameras-quality">
<option value="1">Максимальное</option>
<option value="2">Скорее максимальное</option>
<option value="3">Скорее минимальное</option>
<option value="4">Минимальное</option>
</select>
</div>
<div class="parameters-input">
<label for="cameras-bitrate">Максимальный битрейт</label>
<input name="BR" type="text" id="cameras-bitrate" placeholder="Максимальный битрейт видео">
</div>
<div class="parameters-input">
<label for="cameras-video">Разрешение видео</label>
<select name="RST" id="cameras-video">
<option value="0">352 x 288</option>
<option value="1">352 x 576</option>
<option value="2">704 x 576</option>
<option value="3">176 x 144</option>
<option value="4">320 × 240</option>
<option value="5">640 × 480</option>
<option value="6">1280 x 720</option>
<option value="7">1920 × 1080</option>
</select>
</div>
<div class="parameters-input">
<label for="cameras-alert">Качество видео при предупреждении</label>
<select name="ALT" id="cameras-alert">
<option value="1">Максимальное</option>
<option value="2">Скорее максимальное</option>
<option value="3">Скорее минимальное</option>
<option value="4">Минимальное</option>
</select>
</div>
<div class="parameters-input">
<label for="cameras-ven">Нужно ли видео</label>
<select name="VEN" id="cameras-ven">
<option value="0">Нет</option>
<option value="1">Да</option>
</select>
</div>
<div class="parameters-input">
<label for="cameras-aen">Нужно ли аудио</label>
<select name="AEN" id="cameras-aen">
<option value="0">Нет</option>
<option value="1">Да</option>
</select>
</div>
<div class="parameters-input">
<label for="cameras-framerate">Фреймрейт</label>
<input name="FR" type="text" id="cameras-framerate" placeholder="Фреймрейт видео">
</div>
</div>
<div class="horizontal-line"></div>
<button id="continue-cameras" onclick="updateCamera();" type="button">Сохранить</button>
</div>
</section> </section>
</section> </section>
</section> </section>
@ -571,18 +701,18 @@
async function sendPutRequest() { async function sendPutRequest() {
const dateModSelect = document.getElementById('system-date'); const dateModSelect = document.getElementById('system-date');
const timeFormatSelect = document.getElementById('system-time'); const timeFormatSelect = document.getElementById('system-time');
const videoFormatSelect = document.getElementById('system-video');
const streamFormatSelect = document.getElementById('system-stream'); const streamFormatSelect = document.getElementById('system-stream');
const languageSelect = document.getElementById('system-language'); const languageSelect = document.getElementById('system-language');
const geoModSelect = document.getElementById('system-geo'); const geoModSelect = document.getElementById('system-geo');
const timeZoneSelect = document.getElementById('system-timezone');
// Извлекаем значения выбранных опций // Извлекаем значения выбранных опций
const DATEMOD = dateModSelect.value; const DATEMOD = dateModSelect.value;
const TIMEFORMAT = timeFormatSelect.value; const TIMEFORMAT = timeFormatSelect.value;
const VIDEOFORMAT = videoFormatSelect.value;
const SUBSTREAMMODE = streamFormatSelect.value; const SUBSTREAMMODE = streamFormatSelect.value;
const LANGUAGE = languageSelect.value; const LANGUAGE = languageSelect.value;
const GEOMOD = geoModSelect.value; const GEOMOD = geoModSelect.value;
const TIMEZ = timeZoneSelect.value;
// Извлекаем значения чекбоксов // Извлекаем значения чекбоксов
const NE = document.getElementById('NE').checked ? 1 : 0; const NE = document.getElementById('NE').checked ? 1 : 0;
@ -598,10 +728,10 @@
const requestData = { const requestData = {
DATEMOD, DATEMOD,
TIMEFORMAT, TIMEFORMAT,
VIDEOFORMAT,
SUBSTREAMMODE, SUBSTREAMMODE,
LANGUAGE, LANGUAGE,
GEOMOD, GEOMOD,
TIMEZ,
NE, NE,
TE, TE,
VE, VE,
@ -629,7 +759,6 @@
form.removeClass("form-animation"); form.removeClass("form-animation");
$("body").css("overflow", "auto"); $("body").css("overflow", "auto");
console.log('PUT запрос выполнен успешно'); console.log('PUT запрос выполнен успешно');
// Здесь вы можете выполнить дополнительные действия, если необходимо
} else { } else {
console.error('Ошибка при выполнении PUT запроса'); console.error('Ошибка при выполнении PUT запроса');
} }
@ -689,9 +818,16 @@
var camerasData;
// Открывает popup форму // Открывает popup форму
function openForm(id) { function openForm(id) {
document.getElementById('parameters-bg').style.display = 'flex';
document.getElementById('cameras-bg').style.display = 'flex';
document.getElementById('cameras-id').value = 1;
var formContainer = $("#form-bg"); var formContainer = $("#form-bg");
var form = $("#form"); var form = $("#form");
@ -735,6 +871,20 @@
$("#parameters-equipment-installed").val(formatDate(new Date(response.installation))); $("#parameters-equipment-installed").val(formatDate(new Date(response.installation)));
$("#parameters-device-description").val(response.description); $("#parameters-device-description").val(response.description);
var nowTime = new Date();
var lastkeepalive = new Date(response.lastkeepalive);
var differenceTime = (nowTime - lastkeepalive) / (1000 * 60);
if (differenceTime > 1) {
$("#between-parameters-and-cameras").hide();
$("#stage-parameters-label").hide();
$("#stage-cameras-label").hide();
} else {
$("#between-parameters-and-cameras").show();
$("#stage-parameters-label").show();
$("#stage-cameras-label").show();
}
activeContent = content1 activeContent = content1
switchContent(content1); switchContent(content1);
@ -746,6 +896,8 @@
content4.style.display = "none"; content4.style.display = "none";
content5.style.opacity = 0; content5.style.opacity = 0;
content5.style.display = "none"; content5.style.display = "none";
content6.style.opacity = 0;
content6.style.display = "none";
document.getElementById("stage-details").checked = true; document.getElementById("stage-details").checked = true;
@ -755,16 +907,7 @@
$("body").css("overflow", "hidden"); $("body").css("overflow", "hidden");
const requestBody = { const requestBody = {
"serial": $("#parameters-serial").val(), "serial": $("#parameters-serial").val()
"FIELDS": [
"DATEMOD",
"TIMEFORMAT",
"LANGUAGE",
"VIDEOFORMAT",
"GEOMOD",
"SUBSTREAMMODE",
"DISPLAYMENU"
]
}; };
console.log(requestBody); console.log(requestBody);
@ -779,18 +922,31 @@
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
// Заполняем поля input данными из ответа
document.getElementById('system-date').value = data.DATEMOD; document.getElementById('parameters-bg').style.display = 'none';
document.getElementById('system-time').value = data.TIMEFORMAT; document.getElementById('cameras-bg').style.display = 'none';
document.getElementById('system-language').value = data.LANGUAGE;
document.getElementById('system-video').value = data.VIDEOFORMAT; camerasData = data;
document.getElementById('system-geo').value = data.GEOMOD;
document.getElementById('system-stream').value = data.SUBSTREAMMODE; document.getElementById('system-date').value = data.DATA.TIMEP.DATEM;
document.getElementById('NE').checked = data.DISPLAYMENU.NE === 1; document.getElementById('system-time').value = data.DATA.TIMEP.TIMEM;
document.getElementById('TE').checked = data.DISPLAYMENU.TE === 1; document.getElementById('system-language').value = data.DATA.GSP.LANT;
document.getElementById('VE').checked = data.DISPLAYMENU.VE === 1; document.getElementById('system-timezone').value = data.DATA.TIMEP.TIMEZ;
document.getElementById('SE').checked = data.DISPLAYMENU.SE === 1; document.getElementById('system-geo').value = data.DATA.GSP.GM;
document.getElementById('GE').checked = data.DISPLAYMENU.GE === 1; document.getElementById('system-stream').value = data.DATA.SUBSTRNET.SM;
document.getElementById('NE').checked = data.DATA.DOSD.NE === 1;
document.getElementById('TE').checked = data.DATA.DOSD.TE === 1;
document.getElementById('VE').checked = data.DATA.DOSD.VE === 1;
document.getElementById('SE').checked = data.DATA.DOSD.SE === 1;
document.getElementById('GE').checked = data.DATA.DOSD.GE === 1;
document.getElementById('cameras-quality').value = data.DATA.AR.VEC[0].QLT;
document.getElementById('cameras-bitrate').value = data.DATA.AR.VEC[0].BR;
document.getElementById('cameras-video').value = data.DATA.AR.VEC[0].RST;
document.getElementById('cameras-alert').value = data.DATA.AR.VEC[0].ALT;
document.getElementById('cameras-ven').value = data.DATA.AR.VEC[0].VEN;
document.getElementById('cameras-aen').value = data.DATA.AR.VEC[0].AEN;
document.getElementById('cameras-framerate').value = data.DATA.AR.VEC[0].FR;
}) })
.catch(error => console.error('Ошибка:', error)); .catch(error => console.error('Ошибка:', error));
}, },
@ -800,7 +956,7 @@
} }
}); });
} };
@ -834,6 +990,68 @@
$("body").css("overflow", "auto"); $("body").css("overflow", "auto");
} }
}); });
document.getElementById('cameras-id').addEventListener('change', function() {
var selectedCamera = this.value;
var cameraData = camerasData.DATA.AR.VEC[selectedCamera - 1];
document.getElementById('cameras-quality').value = cameraData.QLT;
document.getElementById('cameras-bitrate').value = cameraData.BR;
document.getElementById('cameras-video').value = cameraData.RST;
document.getElementById('cameras-alert').value = cameraData.ALT;
document.getElementById('cameras-ven').value = cameraData.VEN;
document.getElementById('cameras-aen').value = cameraData.AEN;
document.getElementById('cameras-framerate').value = cameraData.FR;
});
async function updateCamera() {
var selectedCamera = document.getElementById('cameras-id').value;
var cameraData = {
QLT: document.getElementById('cameras-quality').value,
BR: document.getElementById('cameras-bitrate').value,
RST: document.getElementById('cameras-video').value,
ALT: document.getElementById('cameras-alert').value,
VEN: document.getElementById('cameras-ven').value,
AEN: document.getElementById('cameras-aen').value,
FR: document.getElementById('cameras-framerate').value
};
camerasData.DATA.AR.VEC[selectedCamera - 1] = cameraData;
const serial = $("#parameters-serial").val();
try {
// Отправляем PUT запрос
const response = await fetch(`/camera-parameters?serial=${serial}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(camerasData.DATA.AR),
});
if (response.ok) {
// PUT запрос выполнен успешно
var formContainer = $("#form-bg");
var form = $("#form");
formContainer.removeClass("active");
form.removeClass("form-animation");
$("body").css("overflow", "auto");
console.log('PUT запрос выполнен успешно');
} else {
console.error('Ошибка при выполнении PUT запроса');
}
} catch (error) {
console.error('Произошла ошибка при отправке PUT запроса:', error);
}
};
</script> </script>
<script> <script>

View File

@ -253,12 +253,10 @@
cameraSerials.forEach((checkbox) => { cameraSerials.forEach((checkbox) => {
checkbox.addEventListener('change', function() { checkbox.addEventListener('change', function() {
console.log($("input[name=camera-serial]:checked").val())
serial = $("input[name=camera-serial]:checked").val() serial = $("input[name=camera-serial]:checked").val()
stopAllCameras(); stopAllCameras();
currentCameraGroup = 1 currentCameraGroup = 1
totalCameras = $(`#channels-${serial}`).val() - 1; totalCameras = $(`#channels-${serial}`).val() - 1;
console.log(totalCameras);
playNextCamerasInGroup(); playNextCamerasInGroup();
const markers = document.querySelectorAll('.area-devices .device'); const markers = document.querySelectorAll('.area-devices .device');
@ -306,47 +304,73 @@
} }
async function playNextCamerasInGroup() { async function playNextCamerasInGroup() {
const startCamera = (currentCameraGroup - 1) * camerasPerGroup + 2; const startCamera = (currentCameraGroup - 1) * camerasPerGroup + 2;
const endCamera = startCamera + camerasPerGroup - 1; const endCamera = startCamera + camerasPerGroup - 1;
if (startCamera > totalCameras) { if (startCamera > totalCameras) {
// currentCameraGroup = 1; // currentCameraGroup = 1;
// playNextCamerasInGroup(); // playNextCamerasInGroup();
return; return;
} }
stopAllCameras(); stopAllCameras();
let videoElementIndex = 1; let videoElementIndex = 1;
for (let i = startCamera; i <= endCamera && i <= totalCameras; i++) { for (let i = startCamera; i <= endCamera && i <= totalCameras; i++) {
const videoElement = document.getElementById(`camera-${videoElementIndex}`); const videoElement = document.getElementById(`camera-${videoElementIndex}`);
const flvPlayer = flvjs.createPlayer({ let flvPlayer = flvjs.createPlayer({
type: 'flv', type: 'flv',
isLive: true, isLive: true,
cors: true, cors: true,
url: `${baseURL}?serial=${serial}&channel=${i}&quality=0`, url: `${baseURL}?serial=${serial}&channel=${i}&quality=0`,
}, { }, {
enableWorker: true, enableWorker: true,
enableStashBuffer: false, enableStashBuffer: false,
autoCleanupSourceBuffer: true, autoCleanupSourceBuffer: true,
}); });
flvPlayer.attachMediaElement(videoElement); flvPlayer.attachMediaElement(videoElement);
flvPlayer.load(); flvPlayer.load();
flvPlayer.play(); flvPlayer.play();
flvPlayers.push(flvPlayer); flvPlayers.push(flvPlayer);
videoElementIndex++; let hasStarted = false;
await new Promise(resolve => setTimeout(resolve, 1000)); const checkStarted = () => {
} if (!hasStarted && videoElement.readyState >= 2) {
hasStarted = true;
console.log(`Трансляция началась для камеры ${i}`);
} }
};
const checkInterval = setInterval(checkStarted, 1000);
setTimeout(() => {
clearInterval(checkInterval);
if (!hasStarted) {
console.log(`Трансляция для камеры ${i} не началась, запрашиваем повторно...`);
flvPlayer.unload();
flvPlayer.load();
flvPlayer.play();
// if (i > 0) {
// i--;
// }
}
}, 3000);
videoElementIndex++;
await new Promise(resolve => setTimeout(resolve, 4000));
}
}
function switchCameras(direction) { function switchCameras(direction) {
if ((currentCameraGroup === 1 && direction === -1) || (currentCameraGroup === Math.ceil(totalCameras / camerasPerGroup) && direction === 1)) { if ((currentCameraGroup === 1 && direction === -1) || (currentCameraGroup === Math.ceil(totalCameras / camerasPerGroup) && direction === 1)) {
// Если текущая группа - первая и переключаемся назад, или текущая группа - последняя и переключаемся вперед, не переключаемся
return; return;
} }
currentCameraGroup += direction; currentCameraGroup += direction;
@ -420,13 +444,12 @@ const selectedDevices = Array.from(checkboxes)
.filter(checkbox => checkbox.checked && checkbox.value !== 'on') .filter(checkbox => checkbox.checked && checkbox.value !== 'on')
.map(checkbox => checkbox.value)); .map(checkbox => checkbox.value));
console.log(selectedDevices); // Вывести выбранные устройства в консоль
}); });
}); });
function addMarker(device) { function addMarker(device) {
const { serial, status, longitude, latitude, direction, speed, number } = device; const { serial, status, longitude, latitude, direction, speed, number, groupName } = device;
if (serial === $("input[name=camera-serial]:checked").val()) { if (serial === $("input[name=camera-serial]:checked").val()) {
@ -460,7 +483,6 @@ var markerObj = L.marker([latitude, longitude], { icon: marker });
} }
function fetchAndShowMarkers() { function fetchAndShowMarkers() {
console.log(selectedDevices);
fetch('/devices-geo', { fetch('/devices-geo', {
method: 'POST', method: 'POST',
headers: { headers: {
@ -470,11 +492,9 @@ var markerObj = L.marker([latitude, longitude], { icon: marker });
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
console.log(data.devicesData);
clearMarkers(); clearMarkers();
data.devicesData.forEach(device => { data.devicesData.forEach(device => {
addMarker(device); addMarker(device);
console.log(device);
}); });
// Поиск устройства с выбранным серийным номером // Поиск устройства с выбранным серийным номером
@ -488,10 +508,9 @@ var markerObj = L.marker([latitude, longitude], { icon: marker });
const propertiesDiv = document.getElementById('properties'); const propertiesDiv = document.getElementById('properties');
console.log(selectedDevice);
if (selectedDevice) { if (selectedDevice) {
groupElement.textContent = selectedDevice.group; groupElement.textContent = selectedDevice.groupName;
speedElement.textContent = selectedDevice.speed + ' км/ч'; speedElement.textContent = selectedDevice.speed + ' км/ч';
plateElement.textContent = selectedDevice.plate; plateElement.textContent = selectedDevice.plate;
geoElement.textContent = `${selectedDevice.latitude.toFixed(6)}, ${selectedDevice.longitude.toFixed(6)}`; geoElement.textContent = `${selectedDevice.latitude.toFixed(6)}, ${selectedDevice.longitude.toFixed(6)}`;

View File

@ -5,13 +5,36 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Отчёт {{Id}}</title> <title>Отчёт {{Id}}</title>
<!-- <link rel="stylesheet" href="../styles/main.css" /> --> <link rel="stylesheet" href="../styles/main.css" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/Modern-Technologies-SPB/site/static/styles/main.css"> <!-- <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/Modern-Technologies-SPB/site/static/styles/main.css"> -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" /> <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> <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
</head> </head>
<body> <body>
<style>
@page {
size: A4 !important;
margin: 0 !important;
}
@page {
margin-top: 0;
margin-bottom: 0;
}
.page-number::before {
content: none;
}
body {
width: 21cm !important;
height: auto !important;
margin: auto !important;
min-height: 0 !important;
padding: auto !important;
background-color: #fcfcff;
background: repeat center url(../img/argus5.png);
}
</style>
<header> <header>
<img src="../img/argus.png"> <img src="../img/argus.png">
<h1>Аргус</h1> <h1>Аргус</h1>
@ -19,30 +42,24 @@
</header> </header>
<style> <style>
body {
width: 100% !important;
height: 100% !important;
}
.name { .name {
margin-bottom: 50px !important; margin-bottom: 0 !important;
} }
</style> </style>
<section style="margin-left: 0;" class="main"> <section style="margin-left: 0;" class="main">
<div class="name"> <div style="padding: 0; margin-left: 0" class="name">
<span>Отчёт №{{Id}}</span> <span style="padding: 0; margin-left: 2.5%; left: 2.5%;">Отчёт №{{Id}}</span>
</div> </div>
<section style="height: 100% !important;" class="bg">
<section style="position: relative;" class="content"> <section style="position: relative;" class="content">
<div style="position: absolute; left: 2.5%; width: 95%; height: 275px; margin: 25px auto; border-radius: 30px; border: 2px solid rgba(245, 245, 250, 1);" id="map"></div> <div style="position: absolute; left: 2.5%; width: 95%; height: 275px; margin: 25px auto; border-radius: 30px; border: 2px solid rgba(245, 245, 250, 1);" id="map"></div>
<div style="position: absolute; left: 2.5%; width: 95%; height: 250px; margin: 25px auto; border-radius: 30px; border: 2px solid rgba(245, 245, 250, 1); top: 325px;" class="report-info"> <div style="position: absolute; left: 2.5%; width: 95%; height: 250px; margin: 0; border-radius: 30px; border: 2px solid rgba(245, 245, 250, 1); top: 325px; background-color: white !important;" class="report-info">
<ul> <ul>
<li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 19 17"> <li><svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" fill="none" viewBox="0 0 19 17">
@ -67,7 +84,7 @@
</div> </div>
<div style="position: absolute; left: 2.5%; width: 95%; height: 200px; margin: 25px auto; border-radius: 30px; border: 2px solid rgba(245, 245, 250, 1); top: 625px;" class="speedometr"> <div style="position: absolute; left: 2.5%; width: 95%; height: 200px; margin: 0; border-radius: 30px; border: 2px solid rgba(245, 245, 250, 1); top: 625px; background-color: white !important;" class="speedometr">
<h1>Скорость</h1> <h1>Скорость</h1>
<span>км/ч</span> <span>км/ч</span>
<div> <div>
@ -140,7 +157,6 @@
</section>
@ -301,7 +317,23 @@ new Chart("speed", {
}); });
</script> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
<script>
window.addEventListener('load', function() {
document.body.style.zoom = 1;
document.body.style.zoom = "100%";
var printOptions = {
footer: false,
};
window.printOptions = printOptions;
setTimeout(function() {
window.print();
window.close();
}, 2000);
});
</script>
</body> </body>
</html> </html>

View File

@ -91,8 +91,7 @@
<h1>Список предупреждений</h1> <h1>Список предупреждений</h1>
<div class="export"> <div class="export">
<img src="../img/share.svg"> <img src="../img/share.svg">
<!-- <span onclick="generatePDF();">Экспорт</span> --> <span onclick="generatePDF();">Экспорт</span>
<span>Экспорт</span>
</div> </div>
</div> </div>
@ -241,7 +240,7 @@
<script> <script>
function playVideo(channel) { function playVideo(channel) {
const url = `http://localhost:8081/playback?url=http%3A%2F%2Fkrbl.ru%3A8080%2Fhttp%2Fplayback.flv%3Fserial%3D{{Serial}}%26channel%3D${channel}%26quality%3D1%26queryTime%3D{{QueryTime}}%26startTime%3D{{StartTime}}%26endTime%3D{{EndTime}}`; const url = `http://localhost:8081/playback?url=http%3A%2F%2F{{SERVER_IP}}%3A8080%2Fhttp%2Fplayback.flv%3Fserial%3D{{Serial}}%26channel%3D${channel}%26quality%3D1%26queryTime%3D{{QueryTime}}%26startTime%3D{{StartTime}}%26endTime%3D{{EndTime}}`;
window.open(url, '_blank'); window.open(url, '_blank');
} }
</script> </script>

View File

@ -860,7 +860,7 @@ endVideoTimeInput.addEventListener("blur", sendPostRequest);
const serial = selectedDevice.value; const serial = selectedDevice.value;
const url = `http://localhost:8081/export?url=http%3A%2F%2Fkrbl.ru%3A8080%2Fhttp%2Fdownload.flv%3Fserial%3D${serial}%26channel%3D${channel}%26queryTime%3D${selectedDate}%26startTime%3D${startTime}%26endTime%3D${endTime}%26recordID%3D${resData.dataId}`; 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'; document.getElementById("exportLoading").style.display = 'none';
window.open(url, '_blank'); window.open(url, '_blank');
} }

View File

@ -680,7 +680,7 @@ videoTimeInput.addEventListener("blur", sendPostRequest);
selectedChannel = channel; selectedChannel = channel;
const url = `http://localhost:8081/playback?url=http%3A%2F%2Fkrbl.ru%3A8080%2Fhttp%2Fplayback.flv%3Fserial%3D${serial}%26channel%3D${channel}%26quality%3D1%26queryTime%3D${selectedDate}%26startTime%3D${startTime}%26endTime%3D${endTime}`; const url = `http://localhost:8081/playback?url=http%3A%2F%2F{{SERVER_IP}}%3A8080%2Fhttp%2Fplayback.flv%3Fserial%3D${serial}%26channel%3D${channel}%26quality%3D1%26queryTime%3D${selectedDate}%26startTime%3D${startTime}%26endTime%3D${endTime}`;
window.open(url, '_blank'); window.open(url, '_blank');
} }
</script> </script>