ArgusSite/server.js

5273 lines
144 KiB
JavaScript
Raw Permalink Normal View History

2023-07-03 22:31:18 +00:00
const express = require("express");
const app = express();
const path = require("path");
2023-07-16 16:09:25 +00:00
const { Pool } = require("pg");
const fs = require("fs");
const handlebars = require("handlebars");
require("dotenv").config();
const multer = require("multer");
2023-07-24 04:53:11 +00:00
const http = require("http");
const axios = require("axios");
const moment = require("moment");
const bodyParser = require("body-parser");
const _ = require("lodash");
const session = require("express-session");
const bcrypt = require("bcrypt");
2023-07-24 04:53:11 +00:00
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads");
2023-07-24 04:53:11 +00:00
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname);
},
});
const upload = multer({ storage: storage });
2023-07-03 22:31:18 +00:00
app.use(
session({
2023-09-11 10:02:47 +00:00
secret: process.env.SEKRET,
resave: false,
saveUninitialized: true,
cookie: { maxAge: 24 * 60 * 60 * 1000 },
})
);
2023-07-03 22:31:18 +00:00
app.use(express.static(path.join(__dirname, "static")));
2023-07-16 16:09:25 +00:00
app.use(express.json());
2023-07-24 04:53:11 +00:00
app.use(express.urlencoded({ extended: false }));
app.use(bodyParser.json());
2023-07-03 22:31:18 +00:00
app.get("/", index);
app.get("/signin", signin);
2023-07-03 22:31:18 +00:00
app.get("/register", register);
app.get("/live", live);
app.get("/reports", reports);
app.get("/devices", devices);
// app.get("/devices/update", update);
app.get("/devices/groups", groups);
2023-08-21 03:28:58 +00:00
app.get("/videos", videos);
app.get("/videos/export", videoExport);
2023-08-28 04:40:58 +00:00
app.get("/settings", settings);
app.get("/documentation", documentation);
2023-09-11 05:59:00 +00:00
app.get("/admin", adminPanel);
app.get("/admin/organisation", organisation);
2023-08-28 04:40:58 +00:00
async function getUserInfo(userId) {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
try {
let userInfo = {
Organisation: "",
User: "",
Users: [],
EditTransport: false,
DeleteTransport: false,
Update: false,
};
if (userId != "admin") {
const queryUsers = `
SELECT name, surname, devices, edittransport, deletetransport, update
FROM users
WHERE id = $1
`;
const usersResult = await client.query(queryUsers, [userId]);
const user = usersResult.rows[0];
userInfo.Users.push({
name: user.name,
surname: user.surname,
devices: user.devices,
edittransport: user.edittransport,
deletetransport: user.deletetransport,
update: user.update,
});
userInfo.User = user.name + " " + user.surname;
userInfo.EditTransport = user.edittransport;
userInfo.DeleteTransport = user.deletetransport;
userInfo.Update = user.update;
} else {
userInfo.User = "Администратор";
userInfo.EditTransport = true;
userInfo.DeleteTransport = true;
userInfo.Update = true;
}
const queryMain = `SELECT organisation FROM main`;
const mainResult = await client.query(queryMain);
userInfo.Organisation = mainResult.rows[0].organisation;
return userInfo;
} catch (error) {
console.error(error);
throw error;
} finally {
client.release();
}
}
2023-08-28 04:40:58 +00:00
app.post("/videos/restart", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-08-28 04:40:58 +00:00
var options = {
method: "GET",
2023-10-04 20:44:28 +00:00
url: `http://${process.env.VIRTUAL_HOST}/http/restart`,
headers: { "Content-Type": "application/json" },
data: { video: true },
};
2023-08-28 04:40:58 +00:00
axios
.request(options)
.then(function (response) {
res.status(200).json({ message: "Команда для рестарта выполнена." });
return;
})
.catch(function (error) {
console.error(error);
res.status(500).json({ error: "Ошибка сервера" });
return;
});
2023-08-28 04:40:58 +00:00
});
2023-07-03 22:31:18 +00:00
2024-01-09 10:20:04 +00:00
// const DB_User = process.env.DB_USER;
// const DB_Password = process.env.DB_PASSWORD;
// const DB_Host = process.env.DB_HOST;
// const DB_Port = process.env.DB_PORT;
// const DB_Name = process.env.DB_NAME;
2024-01-09 10:18:42 +00:00
2024-01-09 10:20:04 +00:00
const DB_User = "postgres";
const DB_Password = process.env.POSTGRES_PASSWORD;
const DB_Host = "postgres";
const DB_Port = "5432";
const DB_Name = "postgres";
2023-07-16 16:09:25 +00:00
async function index(req, res) {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
const userInfo = await getUserInfo(req.session.userId);
var templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
ifDBError: false,
Count: "",
2023-08-14 04:11:03 +00:00
AlarmsLast11Days: new Array(11).fill(0),
Alarms11DaysBefore: new Array(11).fill(0),
Dates: [],
2023-08-14 04:11:03 +00:00
PositionsLast11Days: new Array(11).fill(0),
};
2023-07-16 16:09:25 +00:00
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
2023-08-21 03:28:58 +00:00
2023-07-16 16:09:25 +00:00
const query = `
SELECT COUNT(*) AS count
FROM registrars
`;
const registrars = await client.query(query);
templateData.Count = registrars.rows[0].count;
2023-07-16 16:09:25 +00:00
let serialValues = [];
if (!templateData.isAdmin) {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await client.query(userDevicesQuery, [
req.session.userId,
]);
2023-09-22 07:55:07 +00:00
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
2023-09-22 07:42:39 +00:00
templateData.Count = serialValues.length;
2023-09-22 07:55:07 +00:00
} else {
templateData.Count = 0;
}
}
2023-08-14 04:11:03 +00:00
const last11DaysQuery = `
2023-08-21 03:28:58 +00:00
WITH date_sequence AS (
2023-10-08 16:08:27 +00:00
SELECT DATE_TRUNC('day', CURRENT_DATE - INTERVAL '10 days') + (generate_series(0, 10) || ' days')::interval AS day
2023-08-21 03:28:58 +00:00
)
SELECT
date_sequence.day AS day,
2023-08-28 06:20:23 +00:00
COALESCE(COUNT(DISTINCT a.evtuuid), 0) AS count
2023-08-21 03:28:58 +00:00
FROM date_sequence
2023-08-28 06:20:23 +00:00
LEFT JOIN (
SELECT DISTINCT ON (evtuuid) evtuuid, time
FROM alarms
WHERE alarmtype = 56
2023-10-08 16:08:27 +00:00
AND time >= CURRENT_DATE - INTERVAL '11 days'
AND time <= CURRENT_DATE + INTERVAL '1 day'
${!templateData.isAdmin ? "AND serial = ANY($1)" : ""}
2023-08-28 06:20:23 +00:00
ORDER BY evtuuid, time DESC
) AS a ON DATE_TRUNC('day', a.time) = date_sequence.day
2023-08-21 03:28:58 +00:00
GROUP BY date_sequence.day
2023-10-08 16:08:27 +00:00
ORDER BY date_sequence.day DESC;
2023-08-14 04:11:03 +00:00
`;
const last11DaysAlarms = await client.query(
last11DaysQuery,
templateData.isAdmin ? [] : [serialValues]
);
2023-08-14 04:11:03 +00:00
const daysBeforeQuery = `
2023-08-28 04:40:58 +00:00
WITH date_sequence AS (
2023-10-08 16:08:27 +00:00
SELECT DATE_TRUNC('day', CURRENT_DATE - INTERVAL '21 days') + (generate_series(0, 10) || ' days')::interval AS day
2023-08-28 04:40:58 +00:00
)
SELECT
date_sequence.day AS day,
2023-08-28 06:20:23 +00:00
COALESCE(COUNT(DISTINCT a.evtuuid), 0) AS count
2023-08-28 04:40:58 +00:00
FROM date_sequence
2023-08-28 06:20:23 +00:00
LEFT JOIN (
SELECT DISTINCT ON (evtuuid) evtuuid, time
FROM alarms
WHERE alarmtype = 56
2023-10-08 16:08:27 +00:00
AND time >= CURRENT_DATE - INTERVAL '21 days'
AND time <= CURRENT_DATE + INTERVAL '10 day'
${!templateData.isAdmin ? "AND serial = ANY($1)" : ""}
2023-08-28 06:20:23 +00:00
ORDER BY evtuuid, time DESC
) AS a ON DATE_TRUNC('day', a.time) = date_sequence.day
2023-08-28 04:40:58 +00:00
GROUP BY date_sequence.day
2023-08-28 06:20:23 +00:00
ORDER BY date_sequence.day DESC;
`;
2023-08-21 03:28:58 +00:00
const daysBeforeAlarms = await client.query(
daysBeforeQuery,
templateData.isAdmin ? [] : [serialValues]
);
2023-08-14 04:11:03 +00:00
const currentDate = new Date();
const dates = [];
2023-08-28 04:40:58 +00:00
const dates11DaysAgo = [];
2023-08-14 04:11:03 +00:00
for (let i = 10; i >= 0; i--) {
const date = new Date(currentDate - i * 24 * 60 * 60 * 1000);
const formattedDate = date.toLocaleDateString("ru-RU", {
day: "2-digit",
month: "2-digit",
});
2023-08-14 04:11:03 +00:00
dates.push(formattedDate);
2023-08-28 04:40:58 +00:00
const date11DaysAgo = new Date(
currentDate - i * 24 * 60 * 60 * 1000 - 11 * 24 * 60 * 60 * 1000
);
const formattedDate11DaysAgo = date11DaysAgo.toLocaleDateString("ru-RU", {
day: "2-digit",
month: "2-digit",
});
2023-08-28 04:40:58 +00:00
dates11DaysAgo.push(formattedDate11DaysAgo);
2023-08-14 04:11:03 +00:00
}
templateData.Dates = dates;
2023-08-28 04:40:58 +00:00
dates11DaysAgo.reverse();
2023-08-14 04:11:03 +00:00
const positionsLast11DaysQuery = `
SELECT
2023-08-21 03:28:58 +00:00
COUNT(*) AS count,
DATE_TRUNC('day', time) AS day,
CASE WHEN COUNT(*) = 0 THEN 0 ELSE 1 END AS sort_value
FROM geo
2023-10-08 16:08:27 +00:00
WHERE time >= CURRENT_DATE - INTERVAL '10 days'
AND time <= CURRENT_DATE + INTERVAL '1 day'
${!templateData.isAdmin ? "AND serial = ANY($1)" : ""}
2023-08-21 03:28:58 +00:00
GROUP BY DATE_TRUNC('day', time)
ORDER BY sort_value DESC, day DESC;
`;
const positionsLast11Days = await client.query(
positionsLast11DaysQuery,
templateData.isAdmin ? [] : [serialValues]
);
2023-08-21 03:28:58 +00:00
templateData.Dates.reverse();
const last11DaysMap = new Map(
last11DaysAlarms.rows.map((row) => [
row.day.toLocaleDateString("ru-RU", {
day: "2-digit",
month: "2-digit",
}),
parseInt(row.count, 10),
])
);
2023-08-21 03:28:58 +00:00
for (let i = 0; i < dates.length; i++) {
const dateKey = dates[i];
templateData.AlarmsLast11Days[i] = last11DaysMap.has(dateKey)
? last11DaysMap.get(dateKey)
: 0;
}
2023-08-21 03:28:58 +00:00
const beforeDaysMap = new Map(
daysBeforeAlarms.rows.map((row) => [
row.day.toLocaleDateString("ru-RU", {
day: "2-digit",
month: "2-digit",
}),
parseInt(row.count, 10),
])
);
2023-08-21 03:28:58 +00:00
for (let i = 0; i < dates.length; i++) {
const dateKey = dates11DaysAgo[i];
templateData.Alarms11DaysBefore[i] = beforeDaysMap.has(dateKey)
? beforeDaysMap.get(dateKey)
: 0;
}
2023-08-21 03:28:58 +00:00
const positionsMap = new Map(
positionsLast11Days.rows.map((row) => [
row.day.toLocaleDateString("ru-RU", {
day: "2-digit",
month: "2-digit",
}),
parseInt(row.count, 10),
])
);
2023-08-21 03:28:58 +00:00
for (let i = 0; i < dates.length; i++) {
const dateKey = dates[i];
templateData.PositionsLast11Days[i] = positionsMap.has(dateKey)
? positionsMap.get(dateKey)
: 0;
}
2023-08-21 03:28:58 +00:00
// console.log(templateData);
2023-07-16 16:09:25 +00:00
const source = fs.readFileSync("static/templates/index.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync("static/templates/index.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-07-16 16:09:25 +00:00
}
2023-07-03 22:31:18 +00:00
}
2023-08-14 04:11:03 +00:00
async function checkLastKeepAlive(serial) {
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
try {
const lastKeepAliveQuery = `SELECT lastkeepalive FROM registrars WHERE serial = $1`;
const lastKeepAliveResult = await client.query(lastKeepAliveQuery, [
serial,
]);
if (lastKeepAliveResult.rows.length > 0) {
const lastKeepAlive = lastKeepAliveResult.rows[0].lastkeepalive;
const currentTime = new Date();
const lastKeepAliveTime = new Date(lastKeepAlive);
const minutesDifference =
(currentTime - lastKeepAliveTime) / (1000 * 60);
if (minutesDifference > 1) {
return false; // lastkeepalive старше минуты
} else {
return true; // lastkeepalive в пределах минуты
}
} else {
return false; // Устройство не найдено
}
} finally {
client.release();
}
} catch (error) {
console.error("Ошибка при проверке lastkeepalive:", error);
throw new Error("Произошла ошибка при проверке lastkeepalive.");
}
}
function signin(req, res) {
if (req.session.userId != undefined) {
return res.redirect("/");
}
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
2023-10-02 13:06:14 +00:00
let templateData = {
Page: "",
2023-10-02 13:06:14 +00:00
};
const page = req.query.page || "";
2023-10-02 13:06:14 +00:00
if (page) {
templateData.Page = page;
}
pool.query("SELECT COUNT(*) FROM main", (error, result) => {
if (error) {
console.error("Ошибка при выполнении запроса к базе данных:", error);
res.status(500).send("Ошибка сервера");
return;
}
const rowCount = parseInt(result.rows[0].count, 10);
if (rowCount === 0) {
res.redirect("/register");
} else {
2023-10-02 13:06:14 +00:00
const source = fs.readFileSync("static/templates/signin.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
});
2023-07-03 22:31:18 +00:00
}
2023-07-03 22:31:18 +00:00
function register(req, res) {
if (req.session.userId != undefined) {
return res.redirect("/");
}
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
pool.query("SELECT COUNT(*) FROM main", (err, result) => {
if (err) {
console.error("Ошибка выполнения SQL-запроса:", err);
res.status(500).send("Внутренняя ошибка сервера");
return;
}
if (result.rows[0].count > 0) {
res.redirect("/signin");
} else {
res.sendFile(path.join(__dirname, "static/templates/register.html"));
}
});
2023-07-03 22:31:18 +00:00
}
app.post("/setup", async (req, res) => {
if (req.session.userId != undefined) {
return res.redirect("/");
}
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const { name, login, password } = req.body;
const checkQuery = "SELECT * FROM main LIMIT 1";
const checkResult = await pool.query(checkQuery);
if (checkResult.rows.length > 0) {
res.redirect("/signin");
}
2023-09-26 13:15:36 +00:00
const hashedPassword = await bcrypt.hash(password, saltRounds);
const insertQuery =
"INSERT INTO main (organisation, login, password) VALUES ($1, $2, $3)";
2023-09-26 13:15:36 +00:00
await pool.query(insertQuery, [name, login, hashedPassword]);
res.status(200).json({ message: "Данные успешно добавлены" });
} catch (error) {
console.error("Ошибка при обработке запроса:", error);
res.status(500).json({ error: "Произошла ошибка при обработке запроса" });
}
});
app.post("/login", async (req, res) => {
if (req.session.userId != undefined) {
return res.redirect("/");
}
const { email, password } = req.body;
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const mainQuery = await pool.query(
"SELECT login, password FROM main WHERE login = $1",
2023-09-26 13:15:36 +00:00
[email]
);
const mainUser = mainQuery.rows[0];
if (mainUser) {
const mainPasswordMatch = await bcrypt.compare(
password,
mainUser.password
);
2023-09-26 13:15:36 +00:00
if (mainPasswordMatch) {
req.session.userId = "admin";
console.log("Авторизация успешна (админ)");
return res.status(200).json({ message: "Авторизация успешна (админ)" });
2023-09-26 13:15:36 +00:00
}
}
const userQuery = await pool.query(
"SELECT id, password FROM users WHERE email = $1",
2023-09-26 13:15:36 +00:00
[email]
);
const user = userQuery.rows[0];
if (!user) {
return res
.status(401)
.json({ message: "Неправильное имя пользователя или пароль" });
}
2023-09-26 13:15:36 +00:00
const passwordMatch = await bcrypt.compare(password, user.password);
if (passwordMatch) {
req.session.userId = user.id;
2023-09-26 13:15:36 +00:00
console.log("Авторизация успешна");
return res.status(200).json({ message: "Авторизация успешна" });
2023-09-26 13:15:36 +00:00
} else {
return res
.status(401)
.json({ message: "Неправильное имя пользователя или пароль" });
2023-09-26 13:15:36 +00:00
}
} catch (error) {
console.error("Ошибка при выполнении запроса к базе данных:", error);
res.status(500).json({ message: "Ошибка сервера" });
}
});
app.get("/logout", (req, res) => {
req.session.destroy((err) => {
if (err) {
console.error("Ошибка при выходе из системы:", err);
res.status(500).json({ message: "Ошибка сервера" });
} else {
res.redirect("/signin");
}
});
});
async function live(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=live");
}
const userInfo = await getUserInfo(req.session.userId);
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
ifDBError: false,
Registrars: [],
2023-08-07 01:15:36 +00:00
Alarms: [],
Count: 0,
Groups: [],
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
2023-08-07 01:15:36 +00:00
const minuteInMillis = 90 * 1000;
2023-08-01 12:35:10 +00:00
let serialValues = [];
if (!templateData.isAdmin) {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await client.query(userDevicesQuery, [
req.session.userId,
]);
2023-09-22 07:55:07 +00:00
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
}
}
const query = `
SELECT id, serial, channels, lastkeepalive, number FROM registrars ${
!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""
} ORDER BY id ASC
`;
const registrars = await client.query(
query,
templateData.isAdmin ? [] : [serialValues]
);
2023-08-01 11:52:35 +00:00
templateData.Registrars = registrars.rows.map((row) => ({
id: row.id,
serial: row.serial,
2023-08-28 04:40:58 +00:00
channels: row.channels,
2023-08-01 12:35:10 +00:00
status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis,
2023-09-19 13:31:40 +00:00
number: row.number,
2023-08-01 11:52:35 +00:00
}));
2023-08-07 01:15:36 +00:00
const subquery = `
SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, r.number, g.latitude, g.longitude
2023-08-13 17:52:23 +00:00
FROM (
SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st
FROM alarms
WHERE alarmtype = 56
${!templateData.isAdmin ? "AND serial = ANY($1)" : ""}
2023-08-13 17:52:23 +00:00
ORDER BY evtuuid, time DESC
) AS a
LEFT JOIN registrars AS r ON a.serial = r.serial
LEFT JOIN (
SELECT *,
2023-10-07 12:50:46 +00:00
ROW_NUMBER() OVER (PARTITION BY serial ORDER BY ABS(EXTRACT(EPOCH FROM (time - NOW())))) AS row_num
2023-08-13 17:52:23 +00:00
FROM geo
) AS g ON a.serial = g.serial AND g.row_num = 1
2023-10-07 00:25:13 +00:00
ORDER BY a.time DESC
LIMIT 100;
2023-08-07 01:15:36 +00:00
`;
const alarms = await client.query(
subquery,
templateData.isAdmin ? [] : [serialValues]
);
2023-08-07 01:15:36 +00:00
function formatDate(date) {
const options = {
year: "2-digit",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
2023-10-08 16:08:27 +00:00
hour12: false,
2023-08-07 01:15:36 +00:00
};
2023-10-08 16:08:27 +00:00
const dateString = date.toISOString().replace("T", " ").slice(0, 19);
const [datePart, timePart] = dateString.split(" ");
const [year, month, day] = datePart.split("-");
const [hour, minute, second] = timePart.split(":");
const formattedDate = `${("0" + day).slice(-2)}.${("0" + month).slice(
-2
)}.${year.slice(-2)} ${("0" + hour).slice(-2)}:${("0" + minute).slice(
-2
)}`;
return formattedDate;
2023-08-07 01:15:36 +00:00
}
templateData.Alarms = alarms.rows.map((alarm) => {
2023-08-07 01:15:36 +00:00
let type;
switch (alarm.st) {
case "0":
type = "Усталость";
break;
case "1":
type = "Водитель пропал";
break;
case "2":
type = "Разговор по телефону";
break;
case "3":
type = "Курение за рулём";
break;
case "4":
type = "Водитель отвлекся";
break;
case "5":
type = "Выезд с полосы движения";
break;
case "6":
type = "!!! Лобовое столкновение";
break;
case "7":
type = "Скорость превышена";
break;
case "8":
type = "Распознавание номерных знаков";
break;
case "9":
type = "!! Маленькое расстояние спереди";
break;
case "10":
type = "Водитель зевает";
break;
case "11":
type = "!!! Столкновение с пешеходом";
break;
case "12":
type = "Проходы переполнены";
break;
case "13":
type = "!! Посадка/высадка вне остановки";
break;
case "14":
type = "!! Смена полосы с нарушением ПДД";
break;
case "15":
type = "! Включенный телефон у водителя";
break;
case "16":
type = "!!! Ремень безопасности";
break;
case "17":
type = "Проверка не удалась";
break;
case "18":
type = "Слепые зоны справа";
break;
case "19":
type = "!!! Заднее столкновение";
break;
case "20":
type = "!!! Управление без рук";
break;
case "21":
type = "!! Управление одной рукой";
break;
case "22":
type = "Очки, блокирующие инфракрасное";
2023-08-07 01:15:36 +00:00
break;
case "23":
type = "Слепые зоны слева";
break;
case "24":
type = "Помехи для пассажиров";
break;
case "25":
type = "На перекрестке ограничена скорость";
break;
case "26":
type = "Обнаружен перекресток";
break;
case "27":
type = "Пешеходы на переходе";
break;
case "28":
type = "! Неучтивое отношение к пешеходам";
break;
case "29":
type = "Обнаружен пешеходный переход";
break;
case "30":
type = "Водитель матерится";
break;
default:
type = "Неизвестный тип";
}
return {
id: alarm.id,
cmdno: alarm.cmdno,
time: formatDate(alarm.time),
number: alarm.number,
2023-08-07 01:15:36 +00:00
serial: alarm.serial,
st: alarm.st,
type: type,
plate: alarm.plate,
latitude: alarm.latitude.toFixed(6),
longitude: alarm.longitude.toFixed(6),
2023-08-07 01:15:36 +00:00
geo: alarm.latitude + "," + alarm.longitude,
};
});
2023-08-07 01:15:36 +00:00
templateData.Count = templateData.Alarms.length;
// Получаем список групп и их идентификаторов из таблицы groups
const groupsQuery = "SELECT id, name FROM groups";
const groupsResult = await client.query(groupsQuery);
const groupsMap = {};
groupsResult.rows.forEach((group) => {
groupsMap[group.id] = group.name;
});
// Выполняем запрос, чтобы получить все данные из таблицы registrars
const queryRegistrars = `
2024-01-08 22:39:00 +00:00
SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port, number, our_registrator
FROM registrars ${!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""}
ORDER BY id
`;
const registrarsResult = await client.query(
queryRegistrars,
templateData.isAdmin ? [] : [serialValues]
);
const allRegistrars = registrarsResult.rows;
const groupedRegistrars = {};
allRegistrars.forEach((registrar) => {
const groupName = groupsMap[registrar.group] || "Другое"; // Используем "Другое", если группа неизвестна
if (!groupedRegistrars[groupName]) {
groupedRegistrars[groupName] = [];
}
groupedRegistrars[groupName].push({
id: registrar.id,
serial: registrar.serial,
channels: registrar.channels,
status:
Date.now() - Date.parse(registrar.lastkeepalive) <= minuteInMillis,
name: registrar.name,
group: groupsMap[registrar.group] || "Другое",
plate: registrar.plate,
sim: registrar.sim,
ip: registrar.ip,
port: registrar.port,
2023-09-19 13:31:40 +00:00
number: registrar.number,
2024-01-08 22:39:00 +00:00
ourreg: registrar.our_registrator,
});
});
templateData.Registrars = allRegistrars.map((registrar) => ({
id: registrar.id,
serial: registrar.serial,
channels: registrar.channels,
status:
Date.now() - Date.parse(registrar.lastkeepalive) <= minuteInMillis,
name: registrar.name,
group: groupsMap[registrar.group] || "Другое",
plate: registrar.plate,
sim: registrar.sim,
ip: registrar.ip,
port: registrar.port,
}));
templateData.Groups = Object.keys(groupedRegistrars).map((groupName) => ({
name: groupName,
devices: groupedRegistrars[groupName],
}));
const source = fs.readFileSync("static/templates/live.html", "utf8");
const template = handlebars.compile(source);
const resultHTML = template(templateData);
res.send(resultHTML);
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync("static/templates/live.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
2023-07-03 22:31:18 +00:00
}
app.post("/devices-geo", async (req, res) => {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=live");
}
const selectedDevices = req.body.devices;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const placeholders = selectedDevices
.map((_, index) => `$${index + 1}`)
.join(",");
const subquery = `
2023-09-19 13:31:40 +00:00
SELECT g.serial, g.longitude, g.latitude, g.direction, g.speed, r.lastkeepalive, r.plate, r.group, r.number
2023-08-01 13:05:54 +00:00
FROM geo g
INNER JOIN (
SELECT serial, MAX(time) AS time
FROM geo
WHERE serial IN (
SELECT serial
FROM registrars
WHERE id IN (${placeholders})
)
GROUP BY serial
2023-08-01 13:05:54 +00:00
) s ON g.serial = s.serial AND g.time = s.time
INNER JOIN registrars r ON g.serial = r.serial
`;
pool.query(subquery, selectedDevices, async (err, result) => {
if (err) {
console.error("Ошибка выполнения запроса:", err);
res.status(500).json({ error: "Ошибка сервера" });
return;
}
2023-08-01 13:05:54 +00:00
const minuteInMillis = 60000;
const devicesData = [];
for (const row of result.rows) {
if (row.speed > 150) {
row.speed /= 100;
}
const groupName = await getGroupNameById(pool, row.group);
const deviceData = {
serial: row.serial,
longitude: row.longitude,
latitude: row.latitude,
direction: row.direction,
speed: row.speed,
status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis,
number: row.number,
plate: row.plate,
group: row.group,
groupName: groupName,
};
devicesData.push(deviceData);
}
2023-08-01 13:05:54 +00:00
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 "Другое";
}
2023-07-16 16:09:25 +00:00
async function reports(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=reports");
}
const userInfo = await getUserInfo(req.session.userId);
2023-07-24 04:53:11 +00:00
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-07-24 04:53:11 +00:00
ifDBError: false,
Registrars: [],
Groups: [],
Count: 0,
2023-07-24 04:53:11 +00:00
};
2023-07-16 16:09:25 +00:00
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
2023-08-13 17:52:23 +00:00
let serialValues = [];
if (!templateData.isAdmin) {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await client.query(userDevicesQuery, [
req.session.userId,
]);
2023-09-22 07:55:07 +00:00
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
}
}
2023-07-16 16:09:25 +00:00
const query = `
2023-09-25 16:37:21 +00:00
SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude, r.number
2023-08-13 17:52:23 +00:00
FROM (
SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st
FROM alarms
WHERE alarmtype = 56
${!templateData.isAdmin ? "AND serial = ANY($1)" : ""}
2023-08-13 17:52:23 +00:00
ORDER BY evtuuid, time DESC
) AS a
LEFT JOIN registrars AS r ON a.serial = r.serial
LEFT JOIN (
SELECT *,
2023-10-07 12:50:46 +00:00
ROW_NUMBER() OVER (PARTITION BY serial ORDER BY ABS(EXTRACT(EPOCH FROM (time - NOW())))) AS row_num
2023-08-13 17:52:23 +00:00
FROM geo
) AS g ON a.serial = g.serial AND g.row_num = 1
2023-10-07 00:25:13 +00:00
ORDER BY a.time DESC
LIMIT 14;
2023-07-16 16:09:25 +00:00
`;
const alarms = await client.query(
query,
templateData.isAdmin ? [] : [serialValues]
);
2023-07-16 16:09:25 +00:00
function formatDate(date) {
const options = {
year: "2-digit",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
2023-10-08 16:08:27 +00:00
hour12: false,
2023-07-16 16:09:25 +00:00
};
2023-10-08 16:08:27 +00:00
const dateString = date.toISOString().replace("T", " ").slice(0, 19);
const [datePart, timePart] = dateString.split(" ");
const [year, month, day] = datePart.split("-");
const [hour, minute, second] = timePart.split(":");
const formattedDate = `${("0" + day).slice(-2)}.${("0" + month).slice(
-2
)}.${year.slice(-2)} ${("0" + hour).slice(-2)}:${("0" + minute).slice(
-2
)}`;
return formattedDate;
2023-07-16 16:09:25 +00:00
}
templateData.Alarms = alarms.rows.map((alarm) => {
2023-07-24 04:53:11 +00:00
let type;
switch (alarm.st) {
case "0":
type = "Усталость";
break;
case "1":
type = "Водитель пропал";
break;
case "2":
type = "Разговор по телефону";
break;
case "3":
type = "Курение за рулём";
break;
case "4":
type = "Водитель отвлекся";
break;
case "5":
type = "Выезд с полосы движения";
break;
case "6":
type = "!!! Лобовое столкновение";
break;
case "7":
type = "Скорость превышена";
break;
case "8":
type = "Распознавание номерных знаков";
break;
case "9":
type = "!! Маленькое расстояние спереди";
break;
case "10":
type = "Водитель зевает";
break;
case "11":
type = "!!! Столкновение с пешеходом";
break;
case "12":
type = "Проходы переполнены";
break;
case "13":
type = "!! Посадка/высадка вне остановки";
break;
case "14":
type = "!! Смена полосы с нарушением ПДД";
break;
case "15":
type = "! Включенный телефон у водителя";
break;
case "16":
type = "!!! Ремень безопасности";
break;
case "17":
type = "Проверка не удалась";
break;
case "18":
type = "Слепые зоны справа";
break;
case "19":
type = "!!! Заднее столкновение";
break;
case "20":
type = "!!! Управление без рук";
break;
case "21":
type = "!! Управление одной рукой";
break;
case "22":
type = "Очки, блокирующие инфракрасное излучение";
break;
case "23":
type = "Слепые зоны слева";
break;
case "24":
type = "Помехи для пассажиров";
break;
case "25":
type = "На перекрестке ограничена скорость";
break;
case "26":
type = "Обнаружен перекресток";
break;
case "27":
type = "Пешеходы на переходе";
break;
case "28":
type = "! Неучтивое отношение к пешеходам";
break;
case "29":
type = "Обнаружен пешеходный переход";
break;
case "30":
type = "Водитель матерится";
break;
default:
type = "Неизвестный тип";
}
return {
id: alarm.id,
cmdno: alarm.cmdno,
time: formatDate(alarm.time),
2023-09-25 16:37:21 +00:00
number: alarm.number,
2023-07-24 04:53:11 +00:00
serial: alarm.serial,
st: alarm.st,
type: type,
plate: alarm.plate,
latitude: alarm.latitude.toFixed(6),
longitude: alarm.longitude.toFixed(6),
geo: alarm.latitude.toFixed(6) + "," + alarm.longitude.toFixed(6),
2023-07-24 04:53:11 +00:00
};
});
2023-07-16 16:09:25 +00:00
const groupsQuery = "SELECT id, name FROM groups";
const groupsResult = await client.query(groupsQuery);
const groupsMap = {};
groupsResult.rows.forEach((group) => {
groupsMap[group.id] = group.name;
});
const minuteInMillis = 90 * 1000;
// Выполняем запрос, чтобы получить все данные из таблицы registrars
const queryRegistrars = `
2023-09-19 13:31:40 +00:00
SELECT id, serial, lastkeepalive, "group", name, plate, sim, ip, port, number
FROM registrars ${!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""}
ORDER BY id
`;
const registrarsResult = await client.query(
queryRegistrars,
templateData.isAdmin ? [] : [serialValues]
);
const allRegistrars = registrarsResult.rows;
const groupedRegistrars = {};
2023-09-19 13:31:40 +00:00
const groupedNumbers = {};
allRegistrars.forEach((registrar) => {
const groupName = groupsMap[registrar.group] || "Другое"; // Используем "Другое", если группа неизвестна
if (!groupedRegistrars[groupName]) {
groupedRegistrars[groupName] = [];
2023-09-19 13:31:40 +00:00
groupedNumbers[groupName] = [];
}
groupedRegistrars[groupName].push(registrar.serial);
2023-09-19 13:31:40 +00:00
groupedNumbers[groupName].push(registrar.number);
});
templateData.Groups = Object.keys(groupedRegistrars).map((groupName) => ({
name: groupName,
serials: groupedRegistrars[groupName],
numbers: groupedNumbers[groupName],
}));
const countQueryText = `
SELECT COUNT(*) AS total
FROM (
SELECT DISTINCT a.evtuuid
FROM alarms AS a
LEFT JOIN registrars AS r ON a.serial = r.serial
LEFT JOIN (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY serial ORDER BY ABS(EXTRACT(EPOCH FROM (time - NOW())))) AS row_num
FROM geo
) AS g ON a.serial = g.serial AND g.row_num = 1
WHERE a.alarmtype = 56
${!templateData.isAdmin ? "AND a.serial = ANY($1)" : ""}
) AS unique_events
`;
const countResult = await pool.query(
countQueryText,
templateData.isAdmin ? [] : [serialValues]
);
templateData.Count = countResult.rows[0].total;
2023-07-16 16:09:25 +00:00
const source = fs.readFileSync(
"static/templates/reports/index.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
} catch (error) {
console.error(error);
2023-07-24 04:53:11 +00:00
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/reports/index.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-07-16 16:09:25 +00:00
}
2023-07-03 22:31:18 +00:00
}
2023-08-13 17:52:23 +00:00
app.post("/getreports", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin?page=reports");
}
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
let serialValues = [];
if (req.session.userId != "admin") {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await pool.query(userDevicesQuery, [
req.session.userId,
]);
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
}
}
const { page, timeRangeStart, timeRangeEnd, serials, searchText } =
req.body;
let timeRangeStartCheck = timeRangeStart;
let timeRangeEndCheck = timeRangeEnd;
let serialsCheck = serials;
console.log(req.body);
if (!timeRangeStartCheck || !timeRangeEndCheck || serialsCheck.length < 1) {
const minMaxSerialQuery = `
SELECT
MIN(time) AS min_date,
MAX(time) AS max_date,
ARRAY_AGG(DISTINCT serial) AS unique_serials
FROM
alarms;
`;
const minMaxDateResult = await pool.query(minMaxSerialQuery);
if (!timeRangeStartCheck) {
timeRangeStartCheck = minMaxDateResult.rows[0].min_date;
}
if (!timeRangeEndCheck) {
timeRangeEndCheck = minMaxDateResult.rows[0].max_date;
}
if (serialsCheck.length < 1) {
if (req.session.userId != "admin") {
serialsCheck = serialValues;
} else {
serialsCheck = minMaxDateResult.rows[0].unique_serials;
}
}
}
const violationsMapping = {
0: "усталость",
1: "водитель пропал",
2: "разговор по телефону",
3: "курение за рулём",
4: "водитель отвлекся",
5: "выезд с полосы движения",
6: "!!! лобовое столкновение",
7: "скорость превышена",
8: "распознавание номерных знаков",
9: "!! маленькое расстояние спереди",
10: "водитель зевает",
11: "!!! столкновение с пешеходом",
12: "проходы переполнены",
13: "!! посадка/высадка вне остановки",
14: "!! смена полосы с нарушением ПДД",
15: "! включенный телефон у водителя",
16: "!!! ремень безопасности",
17: "проверка не удалась",
18: "слепые зоны справа",
19: "!!! заднее столкновение",
20: "!!! управление без рук",
21: "!! управление одной рукой",
22: "очки, блокирующие инфракрасное излучение",
23: "слепые зоны слева",
24: "помехи для пассажиров",
25: "на перекрестке ограничена скорость",
26: "обнаружен перекресток",
27: "пешеходы на переходе",
28: "! неучтивое отношение к пешеходам",
29: "обнаружен пешеходный переход",
30: "водитель матерится",
};
const idList = Object.entries(violationsMapping)
.filter(([id, violation]) => violation.includes(searchText.toLowerCase()))
.map(([id, violation]) => id);
console.log(idList);
const searchConditions = [
"a.evtuuid::TEXT ILIKE $4",
"a.id::TEXT ILIKE $4",
"r.plate::TEXT ILIKE $4",
"a.serial::TEXT ILIKE $4",
"g.latitude::TEXT ILIKE $4",
"g.longitude::TEXT ILIKE $4",
];
const countQueryText = `
SELECT COUNT(*) AS total
FROM (
SELECT DISTINCT a.evtuuid
FROM alarms AS a
LEFT JOIN registrars AS r ON a.serial = r.serial
LEFT JOIN (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY serial ORDER BY ABS(EXTRACT(EPOCH FROM (time - NOW())))) AS row_num
FROM geo
) AS g ON a.serial = g.serial AND g.row_num = 1
WHERE a.alarmtype = 56
AND a.time >= $1::timestamp
AND a.time <= $2::timestamp
AND a.serial = ANY($3)
${
searchText
? `AND (${
idList.length > 0 ? "st = ANY($5) OR" : ""
} (${searchConditions.join(" OR ")}))`
: ""
}
) AS unique_events;
`;
const countValues = [timeRangeStartCheck, timeRangeEndCheck, serialsCheck];
if (searchText.length > 0) {
countValues.push(`%${searchText}%`);
}
if (idList.length > 0 && idList.length !== 31) {
countValues.push(idList);
}
const countResult = await pool.query(countQueryText, countValues);
const totalCount = countResult.rows[0].total;
const queryConditions = [
"a.evtuuid::TEXT ILIKE $6",
"a.id::TEXT ILIKE $6",
"r.plate::TEXT ILIKE $6",
"a.serial::TEXT ILIKE $6",
"g.latitude::TEXT ILIKE $6",
"g.longitude::TEXT ILIKE $6",
];
const queryText = `
SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude, r.number
FROM (
SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st
FROM alarms
WHERE alarmtype = 56
AND time >= $1::timestamp
AND time <= $2::timestamp
ORDER BY evtuuid, time DESC
) AS a
LEFT JOIN registrars AS r ON a.serial = r.serial
LEFT JOIN (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY serial ORDER BY ABS(EXTRACT(EPOCH FROM (time - NOW())))) AS row_num
FROM geo
) AS g ON a.serial = g.serial AND g.row_num = 1
WHERE a.time >= $1::timestamp
AND a.time <= $2::timestamp
AND a.serial = ANY($3)
${
searchText
? `AND (${
idList.length > 0 ? "st = ANY($7) OR" : ""
} (${queryConditions.join(" OR ")}))`
: ``
}
ORDER BY a.time DESC
OFFSET $4 LIMIT $5;
`;
const values = [
timeRangeStartCheck,
timeRangeEndCheck,
serialsCheck,
(page - 1) * 14,
14,
];
if (searchText.length > 0) {
values.push(`%${searchText}%`);
}
if (idList.length > 0 && idList.length !== 31) {
values.push(idList);
}
const result = await pool.query(queryText, values);
function formatDate(date) {
const options = {
year: "2-digit",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
hour12: false,
};
const dateString = date.toISOString().replace("T", " ").slice(0, 19);
const [datePart, timePart] = dateString.split(" ");
const [year, month, day] = datePart.split("-");
const [hour, minute, second] = timePart.split(":");
const formattedDate = `${("0" + day).slice(-2)}.${("0" + month).slice(
-2
)}.${year.slice(-2)} ${("0" + hour).slice(-2)}:${("0" + minute).slice(
-2
)}`;
return formattedDate;
}
const Alarms = result.rows.map((alarm) => {
let type;
switch (alarm.st) {
case "0":
type = "Усталость";
break;
case "1":
type = "Водитель пропал";
break;
case "2":
type = "Разговор по телефону";
break;
case "3":
type = "Курение за рулём";
break;
case "4":
type = "Водитель отвлекся";
break;
case "5":
type = "Выезд с полосы движения";
break;
case "6":
type = "!!! Лобовое столкновение";
break;
case "7":
type = "Скорость превышена";
break;
case "8":
type = "Распознавание номерных знаков";
break;
case "9":
type = "!! Маленькое расстояние спереди";
break;
case "10":
type = "Водитель зевает";
break;
case "11":
type = "!!! Столкновение с пешеходом";
break;
case "12":
type = "Проходы переполнены";
break;
case "13":
type = "!! Посадка/высадка вне остановки";
break;
case "14":
type = "!! Смена полосы с нарушением ПДД";
break;
case "15":
type = "! Включенный телефон у водителя";
break;
case "16":
type = "!!! Ремень безопасности";
break;
case "17":
type = "Проверка не удалась";
break;
case "18":
type = "Слепые зоны справа";
break;
case "19":
type = "!!! Заднее столкновение";
break;
case "20":
type = "!!! Управление без рук";
break;
case "21":
type = "!! Управление одной рукой";
break;
case "22":
type = "Очки, блокирующие инфракрасное излучение";
break;
case "23":
type = "Слепые зоны слева";
break;
case "24":
type = "Помехи для пассажиров";
break;
case "25":
type = "На перекрестке ограничена скорость";
break;
case "26":
type = "Обнаружен перекресток";
break;
case "27":
type = "Пешеходы на переходе";
break;
case "28":
type = "! Неучтивое отношение к пешеходам";
break;
case "29":
type = "Обнаружен пешеходный переход";
break;
case "30":
type = "Водитель матерится";
break;
default:
type = "Неизвестный тип";
}
return {
id: alarm.id,
cmdno: alarm.cmdno,
time: formatDate(alarm.time),
number: alarm.number,
serial: alarm.serial,
st: alarm.st,
type: type,
plate: alarm.plate,
latitude: alarm.latitude.toFixed(6),
longitude: alarm.longitude.toFixed(6),
geo: alarm.latitude.toFixed(6) + "," + alarm.longitude.toFixed(6),
};
});
res.json({
total: totalCount,
data: Alarms,
});
} catch (error) {
console.error("Error handling request:", error);
res.status(500).send("Internal Server Error");
}
});
2023-07-24 04:53:11 +00:00
app.get("/api/devices", async (req, res) => {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=live");
}
2023-07-24 04:53:11 +00:00
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const { page = 1, limit = 10 } = req.query;
const offset = (page - 1) * limit;
let serialValues = [];
if (!templateData.isAdmin) {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await client.query(userDevicesQuery, [
req.session.userId,
]);
2023-09-22 07:55:07 +00:00
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
}
}
2023-07-24 04:53:11 +00:00
const query = `
SELECT a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude
FROM (
SELECT id, cmdno, time, serial, st
FROM alarms
${!templateData.isAdmin ? "WHERE serial = ANY($4)" : ""}
2023-07-24 04:53:11 +00:00
ORDER BY time DESC
LIMIT $1 OFFSET $2
) AS a
LEFT JOIN registrars AS r ON a.serial = r.serial
LEFT JOIN (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY serial ORDER BY ABS(EXTRACT(EPOCH FROM (time - $3)))) AS row_num
FROM geo
) AS g ON a.serial = g.serial AND g.row_num = 1
ORDER BY a.time DESC;
`;
const alarms = await pool.query(
query,
templateData.isAdmin
? [limit, offset, new Date()]
: [limit, offset, new Date(), serialValues]
);
2023-07-24 04:53:11 +00:00
function formatDate(date) {
const options = {
year: "2-digit",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
2023-10-08 16:08:27 +00:00
hour12: false,
2023-07-24 04:53:11 +00:00
};
2023-10-08 16:08:27 +00:00
const dateString = date.toISOString().replace("T", " ").slice(0, 19);
const [datePart, timePart] = dateString.split(" ");
const [year, month, day] = datePart.split("-");
const [hour, minute, second] = timePart.split(":");
const formattedDate = `${("0" + day).slice(-2)}.${("0" + month).slice(
-2
)}.${year.slice(-2)} ${("0" + hour).slice(-2)}:${("0" + minute).slice(
-2
)}`;
return formattedDate;
2023-07-24 04:53:11 +00:00
}
const alarmsData = alarms.rows.map((alarm) => {
let type;
switch (alarm.st) {
case "0":
type = "Усталость";
break;
case "1":
type = "Отсутствие водителя";
break;
case "2":
type = "Разговор по телефону";
break;
default:
type = "Неизвестный тип";
}
return {
id: alarm.id,
cmdno: alarm.cmdno,
time: formatDate(alarm.time),
serial: alarm.serial,
st: alarm.st,
type: type,
plate: alarm.plate,
latitude: alarm.latitude,
longitude: alarm.longitude,
geo: alarm.latitude + "," + alarm.longitude,
};
});
const totalCountQuery = `SELECT COUNT(*) FROM alarms ${
!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""
};`;
const totalCount = await pool.query(
totalCountQuery,
templateData.isAdmin ? [] : [serialValues]
);
2023-07-24 04:53:11 +00:00
const totalPages = Math.ceil(totalCount.rows[0].count / limit);
res.json({
data: alarmsData,
totalPages: totalPages,
});
} catch (error) {
console.error("Error executing query:", error);
res.status(500).json({ error: "Internal server error" });
}
});
app.get("/reports/:id", async (req, res) => {
2023-10-02 13:06:14 +00:00
const id = req.params.id;
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=reports/" + id);
}
const userInfo = await getUserInfo(req.session.userId);
2023-08-07 11:44:15 +00:00
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-08-07 11:44:15 +00:00
ifDBError: false,
Id: id,
Type: "",
Speed: "",
Date: "",
Serial: "",
Geo: "",
2023-08-13 17:52:23 +00:00
Latitude: "",
Longitude: "",
2023-09-10 16:36:39 +00:00
QueryTime: "",
StartTime: "",
EndTime: "",
2023-08-13 17:52:23 +00:00
PrevLatitude: "",
PrevLongitude: "",
NextLatitude: "",
NextLongitude: "",
Speeds: "",
2023-08-07 11:44:15 +00:00
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const minuteInMillis = 90 * 1000;
let serialValues = [];
if (!templateData.isAdmin) {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await client.query(userDevicesQuery, [
req.session.userId,
]);
2023-09-22 07:55:07 +00:00
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
}
}
2023-08-07 11:44:15 +00:00
const query = `
2023-08-13 17:52:23 +00:00
WITH PrevNextGeo AS (
SELECT
a.serial,
a.st,
a.time,
a.geoid,
(SELECT g1.latitude FROM alarms a1 LEFT JOIN geo g1 ON a1.geoid = g1.id WHERE a1.evtuuid = a.evtuuid ORDER BY a1.time ASC LIMIT 1) AS prev_latitude,
(SELECT g2.longitude FROM alarms a2 LEFT JOIN geo g2 ON a2.geoid = g2.id WHERE a2.evtuuid = a.evtuuid ORDER BY a2.time ASC LIMIT 1) AS prev_longitude,
(SELECT g3.latitude FROM alarms a3 LEFT JOIN geo g3 ON a3.geoid = g3.id WHERE a3.evtuuid = a.evtuuid ORDER BY a3.time DESC LIMIT 1) AS next_latitude,
(SELECT g4.longitude FROM alarms a4 LEFT JOIN geo g4 ON a4.geoid = g4.id WHERE a4.evtuuid = a.evtuuid ORDER BY a4.time DESC LIMIT 1) AS next_longitude,
g.longitude,
g.latitude,
g.speed
2023-08-13 17:52:23 +00:00
FROM alarms a
LEFT JOIN geo g ON a.geoid = g.id
WHERE a.id = ${id}
LIMIT 1
),
Speeds AS (
SELECT
g.speed,
ROW_NUMBER() OVER (ORDER BY ABS(EXTRACT(EPOCH FROM (a.time - (SELECT time FROM PrevNextGeo)))) ASC) AS row_number
FROM alarms a
LEFT JOIN geo g ON a.geoid = g.id
WHERE g.serial = (SELECT serial FROM PrevNextGeo) -- Ограничиваем результаты только записями с тем же serial
)
SELECT
*,
(
SELECT array_agg(speed) FROM Speeds
WHERE row_number <= 11
) AS nearest_speeds
FROM PrevNextGeo;
2023-08-07 11:44:15 +00:00
`;
const alarm = (await client.query(query)).rows[0];
2023-08-28 06:20:23 +00:00
// console.log(alarm);
2023-08-07 11:44:15 +00:00
function formatDate(date) {
const options = {
year: "2-digit",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
2023-10-08 16:08:27 +00:00
hour12: false,
2023-08-07 11:44:15 +00:00
};
2023-10-08 16:08:27 +00:00
const dateString = date.toISOString().replace("T", " ").slice(0, 19);
const [datePart, timePart] = dateString.split(" ");
const [year, month, day] = datePart.split("-");
const [hour, minute, second] = timePart.split(":");
const formattedDate = `${("0" + day).slice(-2)}.${("0" + month).slice(
-2
)}.${year.slice(-2)} ${("0" + hour).slice(-2)}:${("0" + minute).slice(
-2
)}`;
return formattedDate;
2023-08-07 11:44:15 +00:00
}
2023-09-10 16:36:39 +00:00
function formatDateToYYYYMMDD(sqlDate) {
const date = new Date(sqlDate);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
2023-09-10 16:36:39 +00:00
return `${year}${month}${day}`;
}
function formatTimeToHHMMSSBefore(sqlDate) {
const date = new Date(sqlDate);
date.setSeconds(date.getSeconds() - 10);
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
2023-09-10 16:36:39 +00:00
return `${hours}${minutes}${seconds}`;
}
function formatTimeToHHMMSSAfter(sqlDate) {
const date = new Date(sqlDate);
date.setSeconds(date.getSeconds() + 10);
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
2023-09-10 16:36:39 +00:00
return `${hours}${minutes}${seconds}`;
}
let type;
switch (alarm.st) {
case "0":
type = "Усталость";
break;
case "1":
type = "Водитель пропал";
break;
case "2":
type = "Разговор по телефону";
break;
case "3":
type = "Курение за рулём";
break;
case "4":
type = "Водитель отвлекся";
break;
case "5":
type = "Выезд с полосы движения";
break;
case "6":
type = "!!! Лобовое столкновение";
break;
case "7":
type = "Скорость превышена";
break;
case "8":
type = "Распознавание номерных знаков";
break;
case "9":
type = "!! Маленькое расстояние спереди";
break;
case "10":
type = "Водитель зевает";
break;
case "11":
type = "!!! Столкновение с пешеходом";
break;
case "12":
type = "Проходы переполнены";
break;
case "13":
type = "!! Посадка/высадка вне остановки";
break;
case "14":
type = "!! Смена полосы с нарушением ПДД";
break;
case "15":
type = "! Включенный телефон у водителя";
break;
case "16":
type = "!!! Ремень безопасности";
break;
case "17":
type = "Проверка не удалась";
break;
case "18":
type = "Слепые зоны справа";
break;
case "19":
type = "!!! Заднее столкновение";
break;
case "20":
type = "!!! Управление без рук";
break;
case "21":
type = "!! Управление одной рукой";
break;
case "22":
type = "Очки, блокирующие инфракрасное излучение";
break;
case "23":
type = "Слепые зоны слева";
break;
case "24":
type = "Помехи для пассажиров";
break;
case "25":
type = "На перекрестке ограничена скорость";
break;
case "26":
type = "Обнаружен перекресток";
break;
case "27":
type = "Пешеходы на переходе";
break;
case "28":
type = "! Неучтивое отношение к пешеходам";
break;
case "29":
type = "Обнаружен пешеходный переход";
break;
case "30":
type = "Водитель матерится";
break;
default:
type = "Неизвестный тип";
}
2023-08-17 09:33:22 +00:00
var actualSpeed;
if (alarm.speed > 150) {
actualSpeed = alarm.speed / 100;
} else {
actualSpeed = alarm.speed;
}
if (serialValues.includes(alarm.serial) || templateData.isAdmin) {
2023-08-07 11:44:15 +00:00
templateData.Type = type;
2023-08-17 09:31:56 +00:00
templateData.Speed = actualSpeed;
2023-08-07 11:44:15 +00:00
templateData.Date = formatDate(alarm.time);
templateData.Serial = alarm.serial;
templateData.Geo = alarm.latitude + "," + alarm.longitude;
templateData.Latitude = alarm.latitude;
templateData.Longitude = alarm.longitude;
2023-09-10 16:36:39 +00:00
templateData.QueryTime = formatDateToYYYYMMDD(alarm.time);
templateData.StartTime = formatTimeToHHMMSSBefore(alarm.time);
templateData.EndTime = formatTimeToHHMMSSAfter(alarm.time);
2023-08-07 11:44:15 +00:00
templateData.PrevLatitude = alarm.prev_latitude;
templateData.PrevLongitude = alarm.prev_longitude;
templateData.NextLatitude = alarm.next_latitude;
templateData.NextLongitude = alarm.next_longitude;
2023-08-13 17:52:23 +00:00
templateData.Speeds = alarm.nearest_speeds;
templateData.Speeds = templateData.Speeds.map((speed) => {
2023-08-17 09:31:56 +00:00
if (speed > 150) {
return speed / 100;
} else {
return speed;
}
});
} else {
console.log("Нет доступа к данному аларму");
templateData.ifDBError = true;
}
2023-08-28 06:20:23 +00:00
// console.log(templateData);
const source = fs.readFileSync(
"static/templates/reports/report.html",
"utf8"
);
2023-08-07 11:44:15 +00:00
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-08-07 11:44:15 +00:00
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/reports/report.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
});
app.get("/generate-pdf/:id", async (req, res) => {
2023-10-02 13:06:14 +00:00
const id = req.params.id;
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=generate-pdf/" + id);
}
const userInfo = await getUserInfo(req.session.userId);
2023-09-06 19:07:19 +00:00
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-09-06 19:07:19 +00:00
ifDBError: false,
Id: id,
Type: "",
Speed: "",
Date: "",
Serial: "",
Geo: "",
Latitude: "",
Longitude: "",
PrevLatitude: "",
PrevLongitude: "",
NextLatitude: "",
NextLongitude: "",
Speeds: "",
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const minuteInMillis = 90 * 1000;
2023-09-06 19:07:19 +00:00
const query = `
WITH PrevNextGeo AS (
SELECT
a.serial,
a.st,
a.time,
a.geoid,
(SELECT g1.latitude FROM alarms a1 LEFT JOIN geo g1 ON a1.geoid = g1.id WHERE a1.evtuuid = a.evtuuid ORDER BY a1.time ASC LIMIT 1) AS prev_latitude,
(SELECT g2.longitude FROM alarms a2 LEFT JOIN geo g2 ON a2.geoid = g2.id WHERE a2.evtuuid = a.evtuuid ORDER BY a2.time ASC LIMIT 1) AS prev_longitude,
(SELECT g3.latitude FROM alarms a3 LEFT JOIN geo g3 ON a3.geoid = g3.id WHERE a3.evtuuid = a.evtuuid ORDER BY a3.time DESC LIMIT 1) AS next_latitude,
(SELECT g4.longitude FROM alarms a4 LEFT JOIN geo g4 ON a4.geoid = g4.id WHERE a4.evtuuid = a.evtuuid ORDER BY a4.time DESC LIMIT 1) AS next_longitude,
g.longitude,
g.latitude,
g.speed
2023-09-06 19:07:19 +00:00
FROM alarms a
LEFT JOIN geo g ON a.geoid = g.id
WHERE a.id = ${id}
LIMIT 1
),
Speeds AS (
SELECT
g.speed,
ROW_NUMBER() OVER (ORDER BY ABS(EXTRACT(EPOCH FROM (a.time - (SELECT time FROM PrevNextGeo)))) ASC) AS row_number
FROM alarms a
LEFT JOIN geo g ON a.geoid = g.id
WHERE g.serial = (SELECT serial FROM PrevNextGeo) -- Ограничиваем результаты только записями с тем же serial
)
SELECT
*,
(
SELECT array_agg(speed) FROM Speeds
WHERE row_number <= 11
) AS nearest_speeds
FROM PrevNextGeo;
`;
const alarm = (await client.query(query)).rows[0];
// console.log(alarm);
function formatDate(date) {
const options = {
year: "2-digit",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
2023-10-08 16:08:27 +00:00
hour12: false,
2023-09-06 19:07:19 +00:00
};
2023-10-08 16:08:27 +00:00
const dateString = date.toISOString().replace("T", " ").slice(0, 19);
const [datePart, timePart] = dateString.split(" ");
const [year, month, day] = datePart.split("-");
const [hour, minute, second] = timePart.split(":");
const formattedDate = `${("0" + day).slice(-2)}.${("0" + month).slice(
-2
)}.${year.slice(-2)} ${("0" + hour).slice(-2)}:${("0" + minute).slice(
-2
)}`;
2023-10-08 16:08:27 +00:00
return formattedDate;
2023-09-06 19:07:19 +00:00
}
let type;
switch (alarm.st) {
case "0":
type = "Усталость";
break;
case "1":
type = "Водитель пропал";
break;
case "2":
type = "Разговор по телефону";
break;
case "3":
type = "Курение за рулём";
break;
case "4":
type = "Водитель отвлекся";
break;
case "5":
type = "Выезд с полосы движения";
break;
case "6":
type = "!!! Лобовое столкновение";
break;
case "7":
type = "Скорость превышена";
break;
case "8":
type = "Распознавание номерных знаков";
break;
case "9":
type = "!! Маленькое расстояние спереди";
break;
case "10":
type = "Водитель зевает";
break;
case "11":
type = "!!! Столкновение с пешеходом";
break;
case "12":
type = "Проходы переполнены";
break;
case "13":
type = "!! Посадка/высадка вне остановки";
break;
case "14":
type = "!! Смена полосы с нарушением ПДД";
break;
case "15":
type = "! Включенный телефон у водителя";
break;
case "16":
type = "!!! Ремень безопасности";
break;
case "17":
type = "Проверка не удалась";
break;
case "18":
type = "Слепые зоны справа";
break;
case "19":
type = "!!! Заднее столкновение";
break;
case "20":
type = "!!! Управление без рук";
break;
case "21":
type = "!! Управление одной рукой";
break;
case "22":
type = "Очки, блокирующие инфракрасное излучение";
break;
case "23":
type = "Слепые зоны слева";
break;
case "24":
type = "Помехи для пассажиров";
break;
case "25":
type = "На перекрестке ограничена скорость";
break;
case "26":
type = "Обнаружен перекресток";
break;
case "27":
type = "Пешеходы на переходе";
break;
case "28":
type = "! Неучтивое отношение к пешеходам";
break;
case "29":
type = "Обнаружен пешеходный переход";
break;
case "30":
type = "Водитель матерится";
break;
default:
type = "Неизвестный тип";
}
var actualSpeed;
if (alarm.speed > 150) {
actualSpeed = alarm.speed / 100;
} else {
actualSpeed = alarm.speed;
}
2023-09-06 19:07:19 +00:00
templateData.Type = type;
templateData.Speed = actualSpeed;
templateData.Date = formatDate(alarm.time);
templateData.Serial = alarm.serial;
templateData.Geo = alarm.latitude + "," + alarm.longitude;
templateData.Latitude = alarm.latitude;
templateData.Longitude = alarm.longitude;
templateData.PrevLatitude = alarm.prev_latitude;
templateData.PrevLongitude = alarm.prev_longitude;
templateData.NextLatitude = alarm.next_latitude;
templateData.NextLongitude = alarm.next_longitude;
templateData.Speeds = alarm.nearest_speeds;
templateData.Speeds = templateData.Speeds.map((speed) => {
if (speed > 150) {
return speed / 100;
2023-09-06 19:07:19 +00:00
} else {
return speed;
2023-09-06 19:07:19 +00:00
}
});
2023-09-06 19:07:19 +00:00
let data = {
Id: templateData.Id,
Organisation: templateData.Organisation,
Type: templateData.Type,
Speed: templateData.Speed,
Date: templateData.Date,
Serial: templateData.Serial,
Geo: templateData.Geo,
PrevLongitude: templateData.PrevLongitude,
PrevLatitude: templateData.PrevLatitude,
NextLongitude: templateData.NextLongitude,
NextLatitude: templateData.NextLatitude,
Speeds: templateData.Speeds,
};
2023-09-06 19:07:19 +00:00
const source = fs.readFileSync("static/templates/reports/pdf.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync("static/templates/reports/pdf.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(data);
res.send(resultT);
}
2023-09-06 19:07:19 +00:00
});
2023-07-16 16:09:25 +00:00
async function devices(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=devices");
}
let userInfo;
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: "",
User: "",
UserInfo: "",
isAdmin: req.session.userId === "admin",
ifDBError: false,
Registrars: [],
Groups: [],
GroupsList: [],
EditTransport: false,
DeleteTransport: false,
Update: false,
};
2023-07-16 16:09:25 +00:00
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
let serialValues = [];
if (!templateData.isAdmin) {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await client.query(userDevicesQuery, [
req.session.userId,
]);
2023-09-22 07:55:07 +00:00
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
}
}
const groupsQuery = "SELECT id, name FROM groups";
const groupsResult = await client.query(groupsQuery);
const groupsMap = {};
groupsResult.rows.forEach((group) => {
groupsMap[group.id] = group.name;
});
const minuteInMillis = 90 * 1000;
2023-08-01 12:35:10 +00:00
const queryRegistrars = `
2023-09-19 13:31:40 +00:00
SELECT id, serial, lastkeepalive, "group", name, plate, sim, ip, port, number
FROM registrars ${!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""}
2023-07-16 16:09:25 +00:00
ORDER BY id
`;
const registrarsResult = await client.query(
queryRegistrars,
templateData.isAdmin ? [] : [serialValues]
);
2023-08-01 12:35:10 +00:00
const allRegistrars = registrarsResult.rows;
const groupedRegistrars = {};
2023-09-19 13:31:40 +00:00
const groupedNumbers = {};
allRegistrars.forEach((registrar) => {
const groupName = groupsMap[registrar.group] || "Другое"; // Используем "Другое", если группа неизвестна
if (!groupedRegistrars[groupName]) {
groupedRegistrars[groupName] = [];
2023-09-19 13:31:40 +00:00
groupedNumbers[groupName] = [];
}
groupedRegistrars[groupName].push(registrar.serial);
2023-09-19 13:31:40 +00:00
groupedNumbers[groupName].push(registrar.number);
});
userInfo = await getUserInfo(req.session.userId);
templateData = {
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
EditTransport: userInfo.EditTransport,
DeleteTransport: userInfo.DeleteTransport,
Update: userInfo.Update,
isAdmin: req.session.userId === "admin",
ifDBError: false,
Registrars: allRegistrars.map((registrar) => ({
id: registrar.id,
2023-09-19 13:31:40 +00:00
number: registrar.number,
serial: registrar.serial,
status:
Date.now() - Date.parse(registrar.lastkeepalive) <= minuteInMillis,
name: registrar.name,
group: groupsMap[registrar.group] || "Другое",
plate: registrar.plate,
sim: registrar.sim,
ip: registrar.ip,
port: registrar.port,
})),
Groups: Object.keys(groupedRegistrars).map((groupName) => ({
name: groupName,
serials: groupedRegistrars[groupName],
2023-09-19 13:31:40 +00:00
numbers: groupedNumbers[groupName],
})),
GroupsList: groupsResult.rows,
};
const source = fs.readFileSync(
"static/templates/devices/index.html",
"utf8"
);
2023-07-16 16:09:25 +00:00
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-07-16 16:09:25 +00:00
client.release();
} catch (error) {
console.error(error);
if (templateData) {
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/devices/index.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
}
}
app.get("/devices/device/system/:serial", async (req, res) => {
2023-10-02 13:06:14 +00:00
const serial = req.params.serial;
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=devices/device/system/" + serial);
2023-09-25 16:37:21 +00:00
}
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
2023-09-25 16:37:21 +00:00
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-09-25 16:37:21 +00:00
ifDBError: false,
Serial: serial,
EditTransport: false,
DeleteTransport: false,
Update: false,
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const source = fs.readFileSync(
"static/templates/devices/system.html",
"utf8"
);
2023-09-25 16:37:21 +00:00
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-09-25 16:37:21 +00:00
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
2023-09-25 16:37:21 +00:00
const source = fs.readFileSync(
"static/templates/devices/system.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
});
app.get("/devices/device/:serial", async (req, res) => {
2023-10-02 13:06:14 +00:00
const serial = req.params.serial;
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=devices/device/" + serial);
2023-09-25 16:37:21 +00:00
}
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
2023-09-25 16:37:21 +00:00
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-09-25 16:37:21 +00:00
ifDBError: false,
Serial: serial,
EditTransport: false,
DeleteTransport: false,
Update: false,
GroupsList: [],
Number: "",
Plate: "",
PlateColor: "",
Channels: "",
Protocol: "",
Ip: "",
Group: "",
Port: "",
Sim: "",
Imei: "",
Imsi: "",
Module: "",
Type: "",
Factory: "",
Capacity: "",
Engine: "",
Stanina: "",
Fuel: "",
Certificate: "",
Category: "",
Expire: "",
Consumption: "",
Region: "",
City: "",
Name: "",
Password: "",
Batch: "",
Release: "",
Installer: "",
Installation: "",
Description: "",
2024-01-08 22:39:00 +00:00
OurRegistrator: "",
2023-09-25 16:37:21 +00:00
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const query = "SELECT * FROM registrars WHERE serial = $1";
const result = await client.query(query, [serial]);
const groupsQuery = "SELECT id, name FROM groups";
const groupsResult = await client.query(groupsQuery);
templateData.GroupsList = groupsResult.rows.map((row) => ({
2023-09-25 16:37:21 +00:00
id: row.id,
name: row.name,
}));
// Предполагается, что результат запроса содержит одну строку данных.
if (result.rows.length === 1) {
const rowData = result.rows[0];
// Заполнение данных из результата SQL запроса в объект templateData.
templateData.Number = rowData.number;
templateData.Plate = rowData.plate;
templateData.PlateColor = rowData.plate_color;
templateData.Channels = rowData.channels;
templateData.Protocol = rowData.protocol;
templateData.Ip = rowData.ip;
templateData.Group = rowData.group;
templateData.Port = rowData.port;
templateData.Sim = rowData.sim;
templateData.Imei = rowData.imei;
templateData.Imsi = rowData.imsi;
templateData.Module = rowData.module;
templateData.Type = rowData.auto;
templateData.Factory = rowData.factory;
templateData.Capacity = rowData.capacity;
templateData.Engine = rowData.engine;
templateData.Stanina = rowData.stanina;
templateData.Fuel = rowData.fuel;
templateData.Certificate = rowData.certificate;
templateData.Category = rowData.category;
templateData.Expire = rowData.certificate_exp;
templateData.Consumption = rowData.consumption;
templateData.Region = rowData.region;
templateData.City = rowData.city;
templateData.Name = rowData.name;
templateData.Password = rowData.password;
templateData.Batch = rowData.batch;
templateData.Release = rowData.release;
templateData.Installer = rowData.installer;
templateData.Installation = rowData.installation;
templateData.Description = rowData.description;
2024-01-08 22:39:00 +00:00
templateData.OurRegistrator = rowData.our_registrator;
2023-09-25 16:37:21 +00:00
}
const source = fs.readFileSync(
"static/templates/devices/device.html",
"utf8"
);
2023-09-25 16:37:21 +00:00
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-09-25 16:37:21 +00:00
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/devices/device.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
});
async function groups(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=devices/groups");
}
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/signin");
}
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
ifDBError: false,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
Groups: [],
EditTransport: userInfo.EditTransport,
DeleteTransport: userInfo.DeleteTransport,
Update: userInfo.Update,
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const result = await client.query("SELECT id, name FROM groups");
const groups = result.rows;
client.release();
templateData.Groups = groups;
const source = fs.readFileSync(
"static/templates/devices/groups.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/devices/groups.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-07-16 16:09:25 +00:00
}
2023-07-03 22:31:18 +00:00
}
2023-07-16 16:09:25 +00:00
app.post("/update-group", async (req, res) => {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=devices/groups");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
try {
const { groupId, newName } = req.body;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const query = "UPDATE groups SET name = $1 WHERE id = $2";
const values = [newName, groupId];
await pool.query(query, values);
res.status(200).json({ message: "Данные группы обновлены успешно" });
} catch (error) {
console.error("Ошибка при обновлении данных группы:", error);
res.status(500).json({ error: "Внутренняя ошибка сервера" });
}
});
async function getParameters(serial) {
const requestResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["EOSD"],
}),
}
);
await new Promise((resolve) => setTimeout(resolve, 300));
const requestResponse2 = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["GSP"],
}),
}
);
2023-09-26 09:45:38 +00:00
await new Promise((resolve) => setTimeout(resolve, 300));
2023-09-26 09:45:38 +00:00
const requestResponse3 = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["TIMEP"],
}),
}
);
await new Promise((resolve) => setTimeout(resolve, 300));
2023-09-26 09:45:38 +00:00
const requestResponse5 = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["AR"],
}),
}
);
// console.log(requestResponse.data);
await new Promise((resolve) => setTimeout(resolve, 300));
const getResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/get?serial=${serial}`
);
return getResponse.data;
}
app.post("/main-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
try {
const { serial } = req.body;
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-26 09:45:38 +00:00
const requestResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["RIP", "VS"],
}),
}
);
2023-09-25 16:37:21 +00:00
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-25 16:37:21 +00:00
const getResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/get?serial=${serial}`
);
2023-09-25 16:37:21 +00:00
res.json(getResponse.data);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal server error" });
2023-09-25 16:37:21 +00:00
}
});
app.put("/main-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
const requestData = req.body;
const { serial } = req.query;
const { NUMBER, PLATE, VIN } = requestData;
2023-09-25 16:37:21 +00:00
const requestBody = {
RIP: {
BN: NUMBER,
BID: PLATE,
},
VS: {
VIN: VIN,
2023-09-25 16:37:21 +00:00
},
};
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/set?serial=${serial}`,
{
data: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
},
2023-09-25 16:37:21 +00:00
}
);
2023-09-25 16:37:21 +00:00
res.status(response.status).send(response.data);
} catch (error) {
res.status(500).send("Произошла ошибка при отправке GET запроса.");
2023-09-25 16:37:21 +00:00
}
});
app.post("/device-parameters", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
try {
const { serial } = req.body;
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-25 16:37:21 +00:00
const responseData = await getParameters(serial);
res.json(responseData);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal server error" });
}
});
app.post("/ethernet-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
try {
const { serial } = req.body;
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-26 09:45:38 +00:00
const requestResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["ETHERNET", "KEYS"],
}),
}
);
2023-09-25 16:37:21 +00:00
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-25 16:37:21 +00:00
const getResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/get?serial=${serial}`
);
2023-09-25 16:37:21 +00:00
res.json(getResponse.data);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal server error" });
2023-09-25 16:37:21 +00:00
}
});
app.put("/ethernet-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
const requestData = req.body;
const { serial } = req.query;
const { IPMODE, IPADDR, SUBMASK, GATEWAY, DNSMODE, PDNS, ADNS, MAC } =
requestData;
2023-09-25 16:37:21 +00:00
const requestBody = {
ETHERNET: {
IPMODE: IPMODE,
PIP: {
IPADDR: IPADDR,
SUBMASK: SUBMASK,
GATEWAY: GATEWAY,
},
DNSMODE: DNSMODE,
DNS: {
PDNS: PDNS,
ADNS: ADNS,
2023-09-25 16:37:21 +00:00
},
},
KEYS: {
MAC: MAC,
},
2023-09-25 16:37:21 +00:00
};
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/set?serial=${serial}`,
{
data: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
},
2023-09-25 16:37:21 +00:00
}
);
2023-09-25 16:37:21 +00:00
res.status(response.status).send(response.data);
} catch (error) {
res.status(500).send("Произошла ошибка при отправке GET запроса.");
2023-09-25 16:37:21 +00:00
}
});
app.post("/wifi-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
try {
const { serial } = req.body;
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-26 09:45:38 +00:00
const requestResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["WIFI"],
}),
}
);
2023-09-25 16:37:21 +00:00
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-25 16:37:21 +00:00
const getResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/get?serial=${serial}`
);
2023-09-25 16:37:21 +00:00
res.json(getResponse.data);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal server error" });
2023-09-25 16:37:21 +00:00
}
});
app.put("/wifi-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
const requestData = req.body;
const { serial } = req.query;
const { WIFI, ESSID, ECRYPTTYPE, PWD, IPMODE, IPADDR, SUBMASK, GATEWAY } =
requestData;
2023-09-25 16:37:21 +00:00
const requestBody = {
WIFI: {
ENABLE: WIFI,
ESSID: ESSID,
ECRYPTTYPE: ECRYPTTYPE,
IPMODE: IPMODE,
PWD: PWD,
PIP: {
IPADDR: IPADDR,
SUBMASK: SUBMASK,
GATEWAY: GATEWAY,
},
},
2023-09-25 16:37:21 +00:00
};
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/set?serial=${serial}`,
{
data: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
},
2023-09-25 16:37:21 +00:00
}
);
2023-09-25 16:37:21 +00:00
res.status(response.status).send(response.data);
} catch (error) {
res.status(500).send("Произошла ошибка при отправке GET запроса.");
2023-09-25 16:37:21 +00:00
}
});
app.post("/communication-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
try {
const { serial } = req.body;
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-26 09:45:38 +00:00
const requestResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["M3G"],
}),
}
);
2023-09-25 16:37:21 +00:00
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-25 16:37:21 +00:00
const getResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/get?serial=${serial}`
);
2023-09-25 16:37:21 +00:00
res.json(getResponse.data);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal server error" });
2023-09-25 16:37:21 +00:00
}
});
app.put("/communication-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
const requestData = req.body;
const { serial } = req.query;
const { NM1, APN1, UN1, PW1, NM2, APN2, UN2, PW2, AT, TN1, TN2, TN3 } =
requestData;
2023-09-25 16:37:21 +00:00
const requestBody = {
M3G: {
M3M: {
AT: AT,
TN1: TN1,
TN2: TN2,
TN3: TN3,
2023-09-25 16:37:21 +00:00
},
MP: {
NM: NM1,
APN: APN1,
UN: UN1,
PW: PW1,
2023-09-25 16:37:21 +00:00
},
M4G: {
NM: NM2,
APN: APN2,
UN: UN2,
PW: PW2,
2023-09-25 16:37:21 +00:00
},
},
2023-09-25 16:37:21 +00:00
};
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/set?serial=${serial}`,
{
data: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
},
2023-09-25 16:37:21 +00:00
}
);
2023-09-25 16:37:21 +00:00
res.status(response.status).send(response.data);
} catch (error) {
res.status(500).send("Произошла ошибка при отправке GET запроса.");
2023-09-25 16:37:21 +00:00
}
});
app.post("/install-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
try {
const { serial } = req.body;
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-26 09:45:38 +00:00
const requestResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["MCMS"],
}),
}
);
2023-09-25 16:37:21 +00:00
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-25 21:45:53 +00:00
const getResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/get?serial=${serial}`
);
2023-09-25 21:45:53 +00:00
res.json(getResponse.data);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal server error" });
2023-09-25 21:45:53 +00:00
}
});
app.post("/ai-parameters", async (req, res) => {
2023-09-25 21:45:53 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 21:45:53 +00:00
try {
const { serial } = req.body;
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-26 09:45:38 +00:00
const requestResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["DSM"],
}),
}
);
2023-09-25 21:45:53 +00:00
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-25 16:37:21 +00:00
const getResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/get?serial=${serial}`
);
2023-09-25 16:37:21 +00:00
res.json(getResponse.data);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal server error" });
2023-09-25 16:37:21 +00:00
}
});
app.put("/ai-parameters", async (req, res) => {
2023-09-26 09:45:38 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
const requestData = req.body;
const { serial } = req.query;
const { DSMA, DSMFE, RWFE } = requestData;
2023-09-26 09:45:38 +00:00
const requestBody = {
DSM: {
DSMA: DSMA,
DSMFE: DSMFE,
RWFE: RWFE,
},
2023-09-26 09:45:38 +00:00
};
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/set?serial=${serial}`,
{
data: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
},
2023-09-26 09:45:38 +00:00
}
);
2023-09-26 09:45:38 +00:00
res.status(response.status).send(response.data);
} catch (error) {
res.status(500).send("Произошла ошибка при отправке GET запроса.");
2023-09-26 09:45:38 +00:00
}
});
app.post("/cameras-parameters", async (req, res) => {
2023-09-26 17:57:39 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
try {
const { serial } = req.body;
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-26 17:57:39 +00:00
const requestResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/request?serial=${serial}`,
{
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
FIELDS: ["MAIN"],
}),
}
);
2023-09-26 17:57:39 +00:00
await new Promise((resolve) => setTimeout(resolve, 1000));
2023-09-26 17:57:39 +00:00
const getResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/get?serial=${serial}`
);
2023-09-26 17:57:39 +00:00
res.json(getResponse.data);
} catch (error) {
console.error(error);
res.status(500).json({ error: "Internal server error" });
2023-09-26 17:57:39 +00:00
}
});
app.put("/cameras-parameters", async (req, res) => {
2023-09-26 17:57:39 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
const requestData = req.body;
const { serial } = req.query;
const { MAIN } = requestData;
2023-09-26 17:57:39 +00:00
const requestBody = {
MAIN: MAIN,
2023-09-26 17:57:39 +00:00
};
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/set?serial=${serial}`,
{
data: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
},
2023-09-26 17:57:39 +00:00
}
);
2023-09-26 17:57:39 +00:00
res.status(response.status).send(response.data);
} catch (error) {
res.status(500).send("Произошла ошибка при отправке GET запроса.");
2023-09-26 17:57:39 +00:00
}
});
app.put("/install-parameters", async (req, res) => {
2023-09-25 16:37:21 +00:00
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-09-25 16:37:21 +00:00
const requestData = req.body;
const { serial } = req.query;
const { SP, M } = requestData;
2023-09-25 16:37:21 +00:00
const requestBody = {
MCMS: {
M: parseInt(M, 10),
SP: SP,
},
2023-09-25 16:37:21 +00:00
};
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/parameters/set?serial=${serial}`,
{
data: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
},
2023-09-25 16:37:21 +00:00
}
);
2023-09-25 16:37:21 +00:00
res.status(response.status).send(response.data);
} catch (error) {
res.status(500).send("Произошла ошибка при отправке GET запроса.");
2023-09-25 16:37:21 +00:00
}
});
app.put("/device-parameters", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
// Получаем данные из PUT запроса
const requestData = req.body;
const { serial } = req.query;
// Извлекаем необходимые параметры
const {
DATEMOD,
TIMEFORMAT,
LANGUAGE,
GEOMOD,
TIMEZ,
NE,
TE,
VE,
SE,
2023-09-25 16:37:21 +00:00
GE,
2023-09-30 13:10:56 +00:00
DE,
TX,
TY,
SX,
SY,
VX,
VY,
GX,
GY,
NX,
NY,
DX,
DY,
} = requestData;
// Создаем JSON для GET запроса
const requestBody = {
TIMEP: {
DATEM: parseInt(DATEMOD, 10),
TIMEM: parseInt(TIMEFORMAT, 10),
TIMEZ: TIMEZ,
},
GSP: {
LANT: parseInt(LANGUAGE, 10),
GM: parseInt(GEOMOD, 10),
},
EOSD: [
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
{
GE: GE,
NE: NE,
SE: SE,
TE: TE,
VE: VE,
DE: DE,
TX: TX,
TY: TY,
SX: SX,
SY: SY,
VX: VX,
VY: VY,
GX: GX,
GY: GY,
NX: NX,
NY: NY,
DX: DX,
DY: DY,
},
],
};
// Отправляем GET запрос с JSON BODY
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/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");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
// Получаем данные из PUT запроса
const camerasData = req.body;
const { serial } = req.query;
// Создаем JSON для GET запроса
const requestBody = {
MAIN: camerasData,
};
// Отправляем GET запрос с JSON BODY
try {
const isLastKeepAliveValid = await checkLastKeepAlive(serial);
if (!isLastKeepAliveValid) {
return res
.status(400)
.send("Ошибка: lastkeepalive старше минуты или устройство не найдено.");
}
const response = await axios.get(
`http://${process.env.VIRTUAL_HOST}/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 запроса.");
}
});
2023-07-16 16:09:25 +00:00
app.post("/devicedata", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-07-16 16:09:25 +00:00
const id = req.body.id;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
2023-07-16 16:09:25 +00:00
const client = await pool.connect();
2023-07-16 16:09:25 +00:00
try {
const query = "SELECT * FROM registrars WHERE id = $1;";
const devicedata = await client.query(query, [id]);
const response = devicedata.rows[0];
res.json(response);
} finally {
client.release();
}
});
app.post("/updatedevice", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
2023-07-24 04:53:11 +00:00
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
2023-07-16 16:09:25 +00:00
const client = await pool.connect();
var {
serialNumber,
2023-09-19 13:31:40 +00:00
deviceNumber,
plateNumber,
2023-09-25 16:37:21 +00:00
vinNumber,
2023-07-16 16:09:25 +00:00
channelsAmount,
2023-09-19 13:31:40 +00:00
plateColor,
2023-07-16 16:09:25 +00:00
IPAddress,
serverPort,
2023-09-19 13:31:40 +00:00
deviceGroup,
connectionProtocol,
2023-07-16 16:09:25 +00:00
sumNumber,
simIMEI,
simIMSI,
simModule,
transportType,
transportFactory,
transportStrength,
transportEngine,
transportStanina,
transportFuel,
transportCertificate,
transportCategory,
transportExpire,
transportConsumption,
transportProvince,
transportCity,
equipmentName,
equipmentPassword,
equipmentNumber,
equipmentReleased,
equipmentInstaller,
equipmentInstalled,
equipmentDescription,
2024-01-08 22:39:00 +00:00
ourRegistrator,
2023-07-16 16:09:25 +00:00
} = req.body;
2024-01-08 22:39:00 +00:00
if (ourRegistrator == "on") {
ourRegistrator = true;
} else {
ourRegistrator = false;
}
2023-07-16 16:09:25 +00:00
try {
const query = `
UPDATE registrars
SET
plate = $1,
plate_color = $2,
channels = $3,
protocol = $4,
ip = $5,
"group" = $6,
port = $7,
sim = $8,
imei = $9,
imsi = $10,
module = $11,
auto = $12,
factory = $13,
capacity = $14,
engine = $15,
stanina = $16,
fuel = $17,
certificate = $18,
category = $19,
certificate_exp = $20,
consumption = $21,
region = $22,
city = $23,
name = $24,
password = $25,
batch = $26,
release = $27,
installer = $28,
installation = $29,
2023-09-19 13:31:40 +00:00
description = $30,
2023-09-25 16:37:21 +00:00
number = $31,
2024-01-08 22:39:00 +00:00
vin = $32,
our_registrator = $33
WHERE serial = $34
2023-07-16 16:09:25 +00:00
RETURNING *;
`;
const values = [
plateNumber,
plateColor,
channelsAmount,
connectionProtocol,
IPAddress,
deviceGroup,
serverPort,
sumNumber,
simIMEI,
simIMSI,
simModule,
transportType,
transportFactory,
transportStrength,
transportEngine,
transportStanina,
transportFuel,
transportCertificate,
transportCategory,
transportExpire,
transportConsumption,
transportProvince,
transportCity,
equipmentName,
equipmentPassword,
equipmentNumber,
equipmentReleased,
equipmentInstaller,
equipmentInstalled,
equipmentDescription,
2023-09-19 13:31:40 +00:00
deviceNumber,
2023-09-25 16:37:21 +00:00
vinNumber,
2024-01-08 22:39:00 +00:00
ourRegistrator,
2023-07-16 16:09:25 +00:00
serialNumber,
];
const result = await client.query(query, values);
const updatedRow = result.rows[0];
2023-08-28 06:20:23 +00:00
// console.log("Updated row:", updatedRow);
2023-07-16 16:09:25 +00:00
res.send("Data updated successfully");
} catch (error) {
console.error("Error updating data:", error);
res.status(500).send("An error occurred while updating data");
} finally {
client.release();
}
});
2023-09-11 05:59:00 +00:00
app.post("/userdata", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-11 05:59:00 +00:00
const id = req.body.id;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
try {
// Выполняем запрос и получаем результат
const query = "SELECT * FROM users WHERE id = $1;";
const userdata = await client.query(query, [id]);
// Формирование и отправка ответа
const response = userdata.rows[0];
res.json(response);
} finally {
client.release();
}
});
app.post("/groupdata", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
const id = req.body.id;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
try {
// Выполняем запрос и получаем результат
const query = "SELECT * FROM groups WHERE id = $1;";
const userdata = await client.query(query, [id]);
// Формирование и отправка ответа
const response = userdata.rows[0];
res.json(response);
} finally {
client.release();
}
});
2023-09-22 19:47:53 +00:00
app.post("/deletedevice", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.DeleteTransport) {
return res.redirect("/devices");
}
2023-09-22 19:47:53 +00:00
const id = req.body.id;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
try {
// Выполняем запрос и получаем результат
const query = "DELETE FROM registrars WHERE id = $1;";
const devicedata = await client.query(query, [id]);
// Формирование и отправка ответа
res.send("Data deleted successfully");
} finally {
client.release();
}
});
2023-09-11 05:59:00 +00:00
app.post("/deleteuser", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
if (req.session.userId != "admin") {
return res.redirect("/signin");
}
2023-09-11 05:59:00 +00:00
const id = req.body.id;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
try {
// Выполняем запрос и получаем результат
const query = "DELETE FROM users WHERE id = $1;";
const userdata = await client.query(query, [id]);
// Формирование и отправка ответа
res.send("Data deleted successfully");
} finally {
client.release();
}
});
app.post("/deletegroup", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
const id = req.body.id;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
try {
// Выполняем запрос и получаем результат
const query = "DELETE FROM groups WHERE id = $1;";
const userdata = await client.query(query, [id]);
// Формирование и отправка ответа
res.send("Data deleted successfully");
} finally {
client.release();
}
});
app.post("/add-group", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-09-26 09:45:38 +00:00
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.EditTransport) {
return res.redirect("/devices");
}
const { name } = req.body;
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const query = `
INSERT INTO groups (name)
VALUES ($1)
RETURNING id
`;
const result = await client.query(query, [name]);
// Освобождение клиента
client.release();
console.log("Группа успешно добавлена");
res.json({ message: "Группа успешно добавлена" });
} catch (err) {
console.error("Ошибка при вставке данных в базу данных:", err);
res.status(500).json({ error: "Ошибка при добавлении пользователя" });
}
});
async function update(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=devices/update");
}
const userInfo = await getUserInfo(req.session.userId);
if (!userInfo.Update) {
return res.redirect("/signin");
}
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
ifDBError: false,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
EditTransport: userInfo.EditTransport,
DeleteTransport: userInfo.DeleteTransport,
Update: userInfo.Update,
};
try {
const source = fs.readFileSync(
"static/templates/devices/update.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/devices/update.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
}
2023-07-03 22:31:18 +00:00
async function settings(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=settings");
}
const userInfo = await getUserInfo(req.session.userId);
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
ifDBError: false,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
};
try {
const source = fs.readFileSync("static/templates/settings.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync("static/templates/settings.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
}
async function documentation(req, res) {
if (req.session.userId === undefined) {
2023-11-07 22:25:16 +00:00
let templateData = {
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
};
const source = fs.readFileSync(
"static/templates/documentation-NA.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
return;
}
const userInfo = await getUserInfo(req.session.userId);
let templateData = {
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
ifDBError: false,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
};
try {
const source = fs.readFileSync(
"static/templates/documentation.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/documentation.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
2023-08-28 04:40:58 +00:00
}
app.get("/download/:filename", (req, res) => {
const filename = req.params.filename;
const filePath = path.join(__dirname, "static", "docs", filename);
// Проверяем существование файла
const exists = require("fs").existsSync(filePath);
if (!exists) {
return res.status(404).send("File not found");
}
// Отправляем файл для скачивания
res.download(filePath, filename, (err) => {
if (err) {
console.error(err);
res.status(500).send("Internal Server Error");
}
});
});
async function organisation(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=admin/organisation");
}
if (req.session.userId != "admin") {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=admin/organisation");
}
const userInfo = await getUserInfo(req.session.userId);
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
ifDBError: false,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
};
try {
const source = fs.readFileSync(
"static/templates/admin/organisation.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/admin/organisation.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
}
app.post("/update-organisation", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
if (req.session.userId != "admin") {
return res.redirect("/signin");
}
try {
const { name } = req.body;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
await client.query("UPDATE main SET organisation = $1 WHERE id = 1", [
name,
]);
client.release();
res.status(200).json({ message: "Значение успешно обновлено" });
} catch (error) {
console.error(error);
res.status(500).json({ error: "Произошла ошибка при обновлении значения" });
}
});
2023-09-11 05:59:00 +00:00
async function adminPanel(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=admin");
}
if (req.session.userId != "admin") {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=admin");
}
const userInfo = await getUserInfo(req.session.userId);
2023-09-11 05:59:00 +00:00
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
2023-09-11 05:59:00 +00:00
ifDBError: false,
Users: [],
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-09-11 05:59:00 +00:00
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const queryUsers = `
SELECT id, name, surname, email, phone, added
FROM users
ORDER BY id
`;
const usersResult = await client.query(queryUsers);
const allUsers = usersResult.rows;
templateData.Users = allUsers.map((user) => ({
id: user.id,
name: user.name,
surname: user.surname,
email: user.email,
phone: user.phone,
added: new Date(user.added).toLocaleDateString("ru-RU", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
}),
}));
2023-09-11 05:59:00 +00:00
// console.log(templateData);
2023-09-11 05:59:00 +00:00
const source = fs.readFileSync("static/templates/admin/index.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-09-11 05:59:00 +00:00
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync("static/templates/admin/index.html", "utf8");
2023-09-11 05:59:00 +00:00
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
}
// Обработка POST-запроса для добавления пользователя
const saltRounds = 10;
2023-09-26 13:15:36 +00:00
2023-09-11 05:59:00 +00:00
app.post("/add-user", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
if (req.session.userId != "admin") {
return res.redirect("/signin");
}
2023-09-11 05:59:00 +00:00
const { name, surname, email, phone, password } = req.body;
try {
2023-09-26 13:15:36 +00:00
const hashedPassword = await bcrypt.hash(password, saltRounds);
2023-09-11 05:59:00 +00:00
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const query = `
2023-09-26 13:15:36 +00:00
INSERT INTO users (name, surname, email, phone, password, added, devices)
VALUES ($1, $2, $3, $4, $5, NOW(), $6)
2023-09-11 05:59:00 +00:00
RETURNING id
`;
const result = await client.query(query, [
name,
surname,
email,
phone,
hashedPassword,
"{}",
]);
2023-09-11 05:59:00 +00:00
// Освобождение клиента
client.release();
console.log("Пользователь успешно добавлен");
res.json({ message: "Пользователь успешно добавлен" });
} catch (err) {
console.error("Ошибка при вставке данных в базу данных:", err);
res.status(500).json({ error: "Ошибка при добавлении пользователя" });
}
});
app.get("/admin/user/:id", async (req, res) => {
2023-10-02 13:06:14 +00:00
const id = req.params.id;
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=admin/user/" + id);
}
if (req.session.userId != "admin") {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=admin/user/" + id);
}
const userInfo = await getUserInfo(req.session.userId);
2023-09-11 05:59:00 +00:00
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-09-11 05:59:00 +00:00
ifDBError: false,
Id: id,
Name: "",
Surname: "",
Email: "",
Phone: "",
Devices: [],
EditTransport: false,
DeleteTransport: false,
Update: false,
Groups: [],
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
const groupsQuery = "SELECT id, name FROM groups";
const groupsResult = await client.query(groupsQuery);
const groupsMap = {};
groupsResult.rows.forEach((group) => {
groupsMap[group.id] = group.name;
});
2023-09-11 05:59:00 +00:00
const minuteInMillis = 90 * 1000;
2023-09-11 05:59:00 +00:00
const queryRegistrars = `
2023-09-19 13:31:40 +00:00
SELECT id, serial, lastkeepalive, "group", name, plate, sim, ip, port, number
FROM registrars
ORDER BY id
`;
const registrarsResult = await client.query(queryRegistrars);
const allRegistrars = registrarsResult.rows;
const groupedRegistrars = {};
const groupedNumbers = {};
allRegistrars.forEach((registrar) => {
const groupName = groupsMap[registrar.group] || "Другое"; // Используем "Другое", если группа неизвестна
if (!groupedRegistrars[groupName]) {
groupedRegistrars[groupName] = [];
groupedNumbers[groupName] = [];
}
groupedRegistrars[groupName].push({
serial: registrar.serial,
checked: false,
});
groupedNumbers[groupName].push(registrar.number);
});
const query = "SELECT * FROM users WHERE id = $1;";
const userdata = await client.query(query, [id]);
const response = userdata.rows[0];
2023-09-11 05:59:00 +00:00
if (response.devices && response.devices.length > 0) {
for (const groupName in groupedRegistrars) {
groupedRegistrars[groupName].forEach((serialObj) => {
serialObj.checked = response.devices.includes(serialObj.serial);
});
}
}
2023-09-11 05:59:00 +00:00
templateData.Name = response.name;
templateData.Surname = response.surname;
templateData.Email = response.email;
templateData.Phone = response.phone;
templateData.Devices = response.devices;
templateData.DeleteTransport = response.deletetransport;
templateData.EditTransport = response.edittransport;
templateData.Update = response.update;
2023-09-11 05:59:00 +00:00
templateData.Groups = Object.keys(groupedRegistrars).map((groupName) => ({
name: groupName,
serials: groupedRegistrars[groupName],
numbers: groupedNumbers[groupName],
}));
2023-09-11 05:59:00 +00:00
const source = fs.readFileSync("static/templates/admin/user.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
2023-09-11 05:59:00 +00:00
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync("static/templates/admin/user.html", "utf8");
2023-09-11 05:59:00 +00:00
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
});
app.post("/updateuser/:id", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
if (req.session.userId != "admin") {
return res.redirect("/signin");
}
2023-09-11 05:59:00 +00:00
const id = req.params.id;
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
var {
name,
surname,
email,
phone,
password,
EditTransport,
DeleteTransport,
Update,
} = req.body.formData;
var devices = req.body.devices;
2023-09-11 05:59:00 +00:00
try {
2023-09-26 13:15:36 +00:00
if (password === "" || password === undefined) {
const query = `
2023-09-26 13:15:36 +00:00
UPDATE users
SET
name = $2,
surname = $3,
email = $4,
phone = $5,
editTransport = $6,
deleteTransport = $7,
update = $8,
devices = $9
WHERE id = $1
RETURNING *;
`;
const values = [
id,
name,
surname,
email,
phone,
EditTransport,
DeleteTransport,
Update,
devices,
];
const result = await client.query(query, values);
} else {
const hashedPassword = await bcrypt.hash(password, saltRounds);
2023-09-26 13:15:36 +00:00
const query = `
2023-09-11 05:59:00 +00:00
UPDATE users
SET
name = $2,
surname = $3,
email = $4,
phone = $5,
password = $6,
editTransport = $7,
deleteTransport = $8,
update = $9,
devices = $10
WHERE id = $1
RETURNING *;
`;
const values = [
id,
name,
surname,
email,
phone,
hashedPassword,
EditTransport,
DeleteTransport,
Update,
devices,
];
const result = await client.query(query, values);
}
2023-09-11 05:59:00 +00:00
res.send("Data updated successfully");
} catch (error) {
console.error("Error updating data:", error);
res.status(500).send("An error occurred while updating data");
} finally {
client.release();
}
});
2023-08-21 03:28:58 +00:00
async function videos(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=videos");
}
const userInfo = await getUserInfo(req.session.userId);
2023-08-21 03:28:58 +00:00
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-08-21 03:28:58 +00:00
ifDBError: false,
Registrars: [],
Groups: [],
2023-08-21 03:28:58 +00:00
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
let serialValues = [];
if (!templateData.isAdmin) {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await client.query(userDevicesQuery, [
req.session.userId,
]);
2023-09-22 07:55:07 +00:00
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
}
}
2023-08-21 03:28:58 +00:00
const minuteInMillis = 60 * 1000;
// Получаем список групп и их идентификаторов из таблицы groups
const groupsQuery = "SELECT id, name FROM groups";
const groupsResult = await client.query(groupsQuery);
const groupsMap = {};
groupsResult.rows.forEach((group) => {
groupsMap[group.id] = group.name;
});
2023-08-21 03:28:58 +00:00
// Выполняем запрос, чтобы получить все данные из таблицы registrars
const queryRegistrars = `
2024-01-08 22:39:00 +00:00
SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port, number, our_registrator
FROM registrars ${!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""}
ORDER BY id
`;
const registrarsResult = await client.query(
queryRegistrars,
templateData.isAdmin ? [] : [serialValues]
);
const allRegistrars = registrarsResult.rows;
const groupedRegistrars = {};
allRegistrars.forEach((registrar) => {
const groupName = groupsMap[registrar.group] || "Другое"; // Используем "Другое", если группа неизвестна
if (!groupedRegistrars[groupName]) {
groupedRegistrars[groupName] = [];
}
groupedRegistrars[groupName].push({
id: registrar.id,
serial: registrar.serial,
channels: registrar.channels,
status:
Date.now() - Date.parse(registrar.lastkeepalive) <= minuteInMillis,
name: registrar.name,
group: groupsMap[registrar.group] || "Другое",
plate: registrar.plate,
sim: registrar.sim,
ip: registrar.ip,
port: registrar.port,
2023-09-19 13:31:40 +00:00
number: registrar.number,
2024-01-08 22:39:00 +00:00
ourreg: registrar.our_registrator,
});
});
templateData.Registrars = allRegistrars.map((registrar) => ({
id: registrar.id,
serial: registrar.serial,
channels: registrar.channels,
status:
Date.now() - Date.parse(registrar.lastkeepalive) <= minuteInMillis,
name: registrar.name,
group: groupsMap[registrar.group] || "Другое",
plate: registrar.plate,
sim: registrar.sim,
ip: registrar.ip,
port: registrar.port,
2024-01-08 22:39:00 +00:00
ourreg: registrar.our_registrator,
}));
templateData.Groups = Object.keys(groupedRegistrars).map((groupName) => ({
name: groupName,
devices: groupedRegistrars[groupName],
}));
2023-08-28 06:20:23 +00:00
// console.log(templateData);
2023-08-21 03:28:58 +00:00
const source = fs.readFileSync(
"static/templates/videos/playback.html",
"utf8"
);
2023-08-28 04:40:58 +00:00
const template = handlebars.compile(source);
const resultHTML = template(templateData);
res.send(resultHTML);
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/videos/playback.html",
"utf8"
);
2023-08-28 04:40:58 +00:00
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
}
async function videoExport(req, res) {
if (req.session.userId === undefined) {
2023-10-02 13:06:14 +00:00
return res.redirect("/signin?page=videos/export");
}
const userInfo = await getUserInfo(req.session.userId);
2023-08-28 04:40:58 +00:00
let templateData = {
2023-10-04 20:44:28 +00:00
VIRTUAL_HOST: process.env.VIRTUAL_HOST,
Organisation: userInfo.Organisation,
User: userInfo.User,
UserInfo: userInfo.Users,
isAdmin: req.session.userId === "admin",
2023-08-28 04:40:58 +00:00
ifDBError: false,
Registrars: [],
Groups: [],
2023-08-28 04:40:58 +00:00
};
try {
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
let serialValues = [];
if (!templateData.isAdmin) {
const userDevicesQuery = `
SELECT devices
FROM users
WHERE id = $1
`;
const userDevicesResult = await client.query(userDevicesQuery, [
req.session.userId,
]);
2023-09-22 07:55:07 +00:00
if (userDevicesResult.rows[0].devices.length > 0) {
serialValues = userDevicesResult.rows[0].devices;
}
}
2023-08-28 04:40:58 +00:00
const minuteInMillis = 60 * 1000;
// Получаем список групп и их идентификаторов из таблицы groups
const groupsQuery = "SELECT id, name FROM groups";
const groupsResult = await client.query(groupsQuery);
const groupsMap = {};
groupsResult.rows.forEach((group) => {
groupsMap[group.id] = group.name;
});
// Выполняем запрос, чтобы получить все данные из таблицы registrars
const queryRegistrars = `
2024-01-09 10:18:42 +00:00
SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port, number, our_registrator
FROM registrars ${!templateData.isAdmin ? "WHERE serial = ANY($1)" : ""}
ORDER BY id
`;
const registrarsResult = await client.query(
queryRegistrars,
templateData.isAdmin ? [] : [serialValues]
);
const allRegistrars = registrarsResult.rows;
const groupedRegistrars = {};
allRegistrars.forEach((registrar) => {
const groupName = groupsMap[registrar.group] || "Другое"; // Используем "Другое", если группа неизвестна
if (!groupedRegistrars[groupName]) {
groupedRegistrars[groupName] = [];
}
groupedRegistrars[groupName].push({
id: registrar.id,
serial: registrar.serial,
channels: registrar.channels,
status:
Date.now() - Date.parse(registrar.lastkeepalive) <= minuteInMillis,
name: registrar.name,
group: groupsMap[registrar.group] || "Другое",
plate: registrar.plate,
sim: registrar.sim,
ip: registrar.ip,
port: registrar.port,
number: registrar.number,
2024-01-09 10:18:42 +00:00
ourreg: registrar.our_registrator,
});
});
templateData.Registrars = allRegistrars.map((registrar) => ({
id: registrar.id,
serial: registrar.serial,
channels: registrar.channels,
status:
Date.now() - Date.parse(registrar.lastkeepalive) <= minuteInMillis,
name: registrar.name,
group: groupsMap[registrar.group] || "Другое",
plate: registrar.plate,
sim: registrar.sim,
ip: registrar.ip,
port: registrar.port,
2024-01-09 10:18:42 +00:00
ourreg: registrar.our_registrator,
}));
templateData.Groups = Object.keys(groupedRegistrars).map((groupName) => ({
name: groupName,
devices: groupedRegistrars[groupName],
}));
2023-08-28 06:20:23 +00:00
// console.log(templateData);
2023-08-28 04:40:58 +00:00
const source = fs.readFileSync(
"static/templates/videos/export.html",
"utf8"
);
2023-08-21 03:28:58 +00:00
const template = handlebars.compile(source);
const resultHTML = template(templateData);
res.send(resultHTML);
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/videos/export.html",
"utf8"
);
2023-08-21 03:28:58 +00:00
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
}
app.get("/getData", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-08-28 11:25:45 +00:00
const selectedSerial = req.query.serial;
const selectedDate = req.query.selectedDate;
const selectedTime = req.query.selectedTime;
const selectedChannel = req.query.selectedChannel;
try {
const successResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/filelist/request?serial=${selectedSerial}&querytime=${selectedDate}&channel=${selectedChannel}`
);
2023-08-28 11:25:45 +00:00
if (successResponse.data.SUCCESS) {
await new Promise((resolve) => setTimeout(resolve, 7000));
const dataResponse = await axios.get(
`http://${process.env.VIRTUAL_HOST}/http/filelist/get?serial=${selectedSerial}&querytime=${selectedDate}&channel=${selectedChannel}`
);
2023-08-28 11:25:45 +00:00
if (successResponse.data.SUCCESS) {
const dataId = dataResponse.data.DATAID;
const dateRanges = dataResponse.data.DATA;
let dataFound = false;
let selectedDataId = null;
const selectedDateTime = moment(
selectedDate + selectedTime,
"YYYYMMDDHHmmss"
).valueOf();
if (dateRanges.length === 1) {
// Если в массиве DATA только одно значение
const [startRange, endRange] = dateRanges[0].split("-");
const startDateTime = moment(startRange, "YYYYMMDDHHmmss").valueOf();
const endDateTime = moment(endRange, "YYYYMMDDHHmmss").valueOf();
if (
!isNaN(selectedDateTime) &&
!isNaN(startDateTime) &&
!isNaN(endDateTime)
) {
if (
selectedDateTime >= startDateTime &&
selectedDateTime <= endDateTime
) {
2023-08-28 11:25:45 +00:00
dataFound = true;
selectedDataId = dataId[0];
2023-08-28 11:25:45 +00:00
}
} else {
console.error("Неверный формат данных для сравнения.");
}
} else {
// Если в массиве DATA больше одного значения
for (let i = 0; i < dateRanges.length; i++) {
const [startRange, endRange] = dateRanges[i].split("-");
const startDateTime = moment(
startRange,
"YYYYMMDDHHmmss"
).valueOf();
const endDateTime = moment(endRange, "YYYYMMDDHHmmss").valueOf();
if (
!isNaN(selectedDateTime) &&
!isNaN(startDateTime) &&
!isNaN(endDateTime)
) {
if (
selectedDateTime >= startDateTime &&
selectedDateTime <= endDateTime
) {
dataFound = true;
selectedDataId = dataId[i];
break;
}
} else {
console.error("Неверный формат данных для сравнения.");
}
}
2023-08-28 11:25:45 +00:00
}
if (dataFound) {
// Здесь можно отправить запрос скоростей и отрисовать график
res.json({ success: true, dataId: selectedDataId });
} else {
res.json({
success: false,
message: "Данных для выбранного периода нет",
});
}
2023-08-28 11:25:45 +00:00
}
} else {
res.json({ success: false, message: "Ошибка при получении данных" });
2023-08-28 11:25:45 +00:00
}
} catch (error) {
console.error("Ошибка при отправке запроса:", error);
res.json({ success: false, message: "Ошибка при отправке запроса" });
2023-08-28 11:25:45 +00:00
}
});
2023-08-21 03:28:58 +00:00
app.post("/getspeedarchive", async (req, res) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
2023-08-21 03:28:58 +00:00
const { serial, datetime } = req.body;
const formattedDateTime = new Date(datetime).toISOString();
const pool = new Pool({
user: DB_User,
host: DB_Host,
database: DB_Name,
password: DB_Password,
port: DB_Port,
});
const client = await pool.connect();
2023-09-17 12:22:14 +00:00
// Запрос для получения первой и последней временных отметок
const timeRangeQuery = `
SELECT MIN(time) as min_time, MAX(time) as max_time
2023-08-21 03:28:58 +00:00
FROM geo
WHERE serial = $1
AND time >= $2
2023-09-17 12:22:14 +00:00
AND time <= $3;
2023-08-21 03:28:58 +00:00
`;
const startTime = new Date(formattedDateTime);
startTime.setMinutes(0, 0, 0); // Округление до начала часа
const endTime = new Date(startTime);
endTime.setHours(endTime.getHours() + 1);
2023-09-17 12:22:14 +00:00
// Первый запрос для получения временных отметок
pool.query(
timeRangeQuery,
[serial, startTime, endTime],
(error, timeResults) => {
if (error) {
console.error("Ошибка при выполнении SQL-запроса:", error);
res.status(500).json({ error: "Ошибка на сервере" });
} else {
const { min_time, max_time } = timeResults.rows[0];
2023-09-17 12:22:14 +00:00
// Запрос для получения данных скорости и геолокации
const sqlQuery = `
2023-09-17 12:22:14 +00:00
SELECT speed, latitude, longitude, time
FROM geo
WHERE serial = $1
AND time >= $2
AND time <= $3;
`;
pool.query(sqlQuery, [serial, startTime, endTime], (error, results) => {
if (error) {
console.error("Ошибка при выполнении SQL-запроса:", error);
res.status(500).json({ error: "Ошибка на сервере" });
} else {
const data = results.rows.map((row) => ({
speed: row.speed > 150 ? row.speed / 100 : row.speed,
geo: {
latitude: row.latitude,
longitude: row.longitude,
},
time: row.time.toLocaleTimeString("ru-RU", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
}),
}));
// Функция для сравнения времени в формате "час:минута"
function compareTime(a, b) {
return (
new Date("1970-01-01 " + a.time) -
new Date("1970-01-01 " + b.time)
);
}
2023-09-17 12:22:14 +00:00
// Сортируем массив данных
data.sort(compareTime);
2023-09-17 12:22:14 +00:00
// Разделяем отсортированный массив обратно на отдельные массивы
const transformedSpeeds = data.map((item) => item.speed);
const geoData = data.map((item) => item.geo);
const names = data.map((item) => item.time);
2023-09-17 12:22:14 +00:00
res.json({ speeds: transformedSpeeds, geo: geoData, names });
}
});
}
2023-08-21 03:28:58 +00:00
}
);
2023-08-21 03:28:58 +00:00
});
2023-07-03 22:31:18 +00:00
const port = 8081;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
app.use((req, res, next) => {
if (req.session.userId === undefined) {
return res.redirect("/signin");
}
res.sendFile(path.join(__dirname, "static/templates/404.html"));
});