ArgusSite/server.js

1358 lines
36 KiB
JavaScript
Raw 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 storage = multer.diskStorage({
destination: function (req, file, cb) {
2023-08-13 17:52:23 +00:00
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(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 }));
2023-07-03 22:31:18 +00:00
app.get("/", index);
app.get("/login", login);
app.get("/register", register);
app.get("/live", live);
app.get("/reports", reports);
app.get("/devices", devices);
app.get("/devices/drivers", drivers);
app.get("/devices/update", update);
2023-07-03 22:31:18 +00:00
2023-07-16 17:02:59 +00:00
2023-08-13 17:52:23 +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;
2023-08-01 13:05:54 +00:00
2023-08-13 17:52:23 +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) {
var templateData = {
Organisation: "Название организации",
User: "Тестовое Имя",
ifDBError: false,
Count: "",
};
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-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
console.log(templateData);
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
}
function login(req, res) {
res.sendFile(path.join(__dirname, "static/templates/login.html"));
}
function register(req, res) {
res.sendFile(path.join(__dirname, "static/templates/register.html"));
}
async function live(req, res) {
let templateData = {
Organisation: "Название организации",
User: "Тестовое Имя",
ifDBError: false,
Registrars: [],
2023-08-07 01:15:36 +00:00
Alarms: [],
Count: 0,
};
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
const query = `
2023-08-01 12:35:10 +00:00
SELECT id, serial, lastkeepalive FROM registrars ORDER BY id ASC
`;
const registrars = await client.query(query);
2023-08-01 11:52:35 +00:00
templateData.Registrars = registrars.rows.map((row) => ({
id: row.id,
serial: row.serial,
2023-08-01 12:35:10 +00:00
status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis,
2023-08-01 11:52:35 +00:00
}));
2023-08-07 01:15:36 +00:00
const subquery = `
2023-08-13 17:52:23 +00:00
SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude
FROM (
SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st
FROM alarms
WHERE alarmtype = 56
ORDER BY evtuuid, time DESC
LIMIT 100
) 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 - $1)))) AS row_num
FROM geo
) AS g ON a.serial = g.serial AND g.row_num = 1
ORDER BY a.time DESC;
2023-08-07 01:15:36 +00:00
`;
2023-08-13 17:52:23 +00:00
const alarms = await client.query(subquery, [new Date()]);
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-08-13 17:52:23 +00:00
const adjustedDate = new Date(date);
adjustedDate.setHours(adjustedDate.getHours() - 3);
const formattedDate = adjustedDate.toLocaleString("ru-RU", options);
2023-08-07 01:15:36 +00:00
return formattedDate.replace(",", "");
}
(templateData.Alarms = alarms.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),
serial: alarm.serial,
st: alarm.st,
type: type,
plate: alarm.plate,
latitude: (alarm.latitude).toFixed(6),
longitude: (alarm.longitude).toFixed(6),
geo: alarm.latitude + "," + alarm.longitude,
};
}))
templateData.Count = templateData.Alarms.length;
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) => {
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
2023-08-01 13:05:54 +00:00
.map((_, index) => `$${index + 1}`)
.join(",");
const subquery = `
2023-08-01 13:05:54 +00:00
SELECT g.serial, g.longitude, g.latitude, g.direction, g.speed, r.lastkeepalive
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, (err, result) => {
if (err) {
console.error("Ошибка выполнения запроса:", err);
res.status(500).json({ error: "Ошибка сервера" });
return;
}
const minuteInMillis = 60000;
const devicesData = result.rows.map((row) => ({
serial: row.serial,
longitude: row.longitude,
latitude: row.latitude,
direction: row.direction,
speed: row.speed,
status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis,
}));
res.json({ devicesData });
});
});
2023-07-16 16:09:25 +00:00
async function reports(req, res) {
2023-07-24 04:53:11 +00:00
let templateData = {
Organisation: "Название организации",
User: "Тестовое Имя",
ifDBError: false,
Registrars: [],
};
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
2023-07-16 16:09:25 +00:00
const query = `
2023-08-13 17:52:23 +00:00
SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude
FROM (
SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st
FROM alarms
WHERE alarmtype = 56
ORDER BY evtuuid, time DESC
LIMIT 100
) 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 - $1)))) AS row_num
FROM geo
) AS g ON a.serial = g.serial AND g.row_num = 1
ORDER BY a.time DESC;
2023-07-16 16:09:25 +00:00
`;
2023-08-13 17:52:23 +00:00
const alarms = await client.query(query, [new Date()]);
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-08-13 17:52:23 +00:00
const adjustedDate = new Date(date);
adjustedDate.setHours(adjustedDate.getHours() - 3);
const formattedDate = adjustedDate.toLocaleString("ru-RU", options);
2023-07-16 16:09:25 +00:00
return formattedDate.replace(",", "");
}
2023-07-24 04:53:11 +00:00
(templateData.Alarms = alarms.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),
serial: alarm.serial,
st: alarm.st,
type: type,
plate: alarm.plate,
2023-08-07 01:15:36 +00:00
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-08-07 01:15:36 +00:00
}))
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
2023-07-24 04:53:11 +00:00
app.get("/api/devices", async (req, res) => {
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;
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
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;
`;
2023-08-07 11:44:15 +00:00
const alarms = await pool.query(query, [limit, offset, new Date()]);
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-08-13 17:52:23 +00:00
const adjustedDate = new Date(date);
adjustedDate.setHours(adjustedDate.getHours() - 3);
const formattedDate = adjustedDate.toLocaleString("ru-RU", options);
2023-07-24 04:53:11 +00:00
return formattedDate.replace(",", "");
}
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;";
const totalCount = await pool.query(totalCountQuery);
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" });
}
});
2023-08-07 11:44:15 +00:00
app.get('/reports/:id', async (req, res) => {
const id = req.params.id;
let templateData = {
Organisation: "Название организации",
User: "Тестовое Имя",
ifDBError: false,
Id: id,
Type: "",
Speed: "",
Date: "",
Serial: "",
Geo: "",
2023-08-13 17:52:23 +00:00
Latitude: "",
Longitude: "",
2023-08-07 11:44:15 +00:00
DriverName: "",
DriverPhone: "",
DriverEmail: "",
DriverLicense: "",
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;
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,
d.name,
d.surname,
d.card,
d.phone,
d.email
FROM alarms a
LEFT JOIN geo g ON a.geoid = g.id
LEFT JOIN drivers d ON a.serial = d.transport
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];
console.log(alarm);
function formatDate(date) {
const options = {
year: "2-digit",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
};
2023-08-13 17:52:23 +00:00
const adjustedDate = new Date(date);
adjustedDate.setHours(adjustedDate.getHours() - 3);
const formattedDate = adjustedDate.toLocaleString("ru-RU", options);
2023-08-07 11:44:15 +00:00
return formattedDate.replace(",", "");
}
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 = "Неизвестный тип";
}
templateData.Type = type;
templateData.Speed = alarm.speed;
templateData.Date = formatDate(alarm.time);
templateData.Serial = alarm.serial;
templateData.Geo = alarm.latitude + "," + alarm.longitude;
2023-08-13 17:52:23 +00:00
templateData.Latitude = alarm.latitude
templateData.Longitude = alarm.longitude
2023-08-07 11:44:15 +00:00
templateData.DriverName = alarm.name + " " + alarm.surname;
templateData.DriverPhone = alarm.phone;
templateData.DriverEmail = alarm.email;
templateData.DriverLicense = alarm.card;
2023-08-13 17:52:23 +00:00
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;
2023-08-07 11:44:15 +00:00
console.log(templateData);
const source = fs.readFileSync("static/templates/reports/report.html", "utf8");
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
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);
}
});
2023-07-16 16:09:25 +00:00
async function devices(req, res) {
let templateData = {
Organisation: "Название организации",
User: "Тестовое Имя",
ifDBError: false,
Registrars: [],
};
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-01 12:35:10 +00:00
2023-08-07 01:15:36 +00:00
const minuteInMillis = 90 * 1000;
2023-08-01 12:35:10 +00:00
// Выполняем запрос, чтобы получить все данные из таблицы registrars
const queryRegistrars = `
SELECT id, serial, lastkeepalive, name, "group", plate, sim, ip, port
2023-07-16 16:09:25 +00:00
FROM registrars
ORDER BY id
`;
2023-08-01 12:35:10 +00:00
const registrarsResult = await client.query(queryRegistrars);
const allRegistrars = registrarsResult.rows;
// Определяем статус connected на основе lastkeepalive
2023-08-07 11:44:15 +00:00
templateData.Registrars = allRegistrars.map((registrar) => ({
id: registrar.id,
serial: registrar.serial,
2023-08-01 12:35:10 +00:00
status: Date.now() - Date.parse(registrar.lastkeepalive) <= minuteInMillis,
name: registrar.name,
group: registrar.group,
plate: registrar.plate,
sim: registrar.sim,
ip: registrar.ip,
port: registrar.port,
})),
2023-08-01 12:35:10 +00:00
2023-07-16 16:09:25 +00:00
console.log(templateData);
2023-08-01 12:35:10 +00:00
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-08-01 12:35:10 +00:00
2023-07-16 16:09:25 +00:00
client.release();
} catch (error) {
console.error(error);
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);
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("/devicedata", async (req, res) => {
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) => {
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 {
plateNumber,
plateColor,
serialNumber,
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,
} = req.body;
try {
2023-08-13 17:52:23 +00:00
2023-07-16 16:09:25 +00:00
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,
description = $30
WHERE serial = $31
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,
serialNumber,
];
const result = await client.query(query, values);
const updatedRow = result.rows[0];
console.log("Updated row:", updatedRow);
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-07-24 04:53:11 +00:00
app.post("/updatedriver", upload.single("upload-file"), async (req, res) => {
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 {
driverName,
driverSurname,
driverCard,
driverGender,
driverLicense,
driverPassport,
driverPhone,
driverEmail,
driverTransport,
driverDescription,
driverID,
} = req.body;
try {
// Вставка новой строки в таблицу drivers
const query = `
UPDATE drivers
SET name = $1,
surname = $2,
card = $3,
gender = $4,
license = $5,
passport = $6,
phone = $7,
email = $8,
transport = $9,
description = $10
WHERE id = $11
RETURNING *;
`;
const values = [
driverName,
driverSurname,
driverCard,
driverGender,
driverLicense,
driverPassport,
driverPhone,
driverEmail,
driverTransport,
driverDescription,
driverID,
];
const result = await client.query(query, values);
const newRow = result.rows[0];
console.log("New driver added:", newRow);
res.send("Data added successfully");
} catch (error) {
console.error("Error adding data:", error);
res.status(500).send("An error occurred while adding data");
} finally {
client.release();
}
});
app.post("/adddriver", upload.single("upload-file"), async (req, res) => {
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 {
driverName,
driverSurname,
driverCard,
driverGender,
driverLicense,
driverPassport,
driverPhone,
driverEmail,
driverTransport,
driverDescription,
} = req.body;
try {
// Вставка новой строки в таблицу drivers
const query = `
INSERT INTO drivers (
name,
surname,
card,
gender,
license,
passport,
phone,
email,
transport,
description
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING *;
`;
const values = [
driverName,
driverSurname,
driverCard,
driverGender,
driverLicense,
driverPassport,
driverPhone,
driverEmail,
driverTransport,
driverDescription,
];
const result = await client.query(query, values);
const newRow = result.rows[0];
console.log("New driver added:", newRow);
res.send("Data added successfully");
} catch (error) {
console.error("Error adding data:", error);
res.status(500).send("An error occurred while adding data");
} finally {
client.release();
}
});
app.post("/driverdata", async (req, res) => {
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 drivers WHERE id = $1;";
const driverdata = await client.query(query, [id]);
// Формирование и отправка ответа
const response = driverdata.rows[0];
res.json(response);
} finally {
client.release();
}
});
app.post("/deletedriver", async (req, res) => {
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 drivers WHERE id = $1;";
const driverdata = await client.query(query, [id]);
// Формирование и отправка ответа
res.send("Data deleted successfully");
} finally {
client.release();
}
});
async function drivers(req, res) {
let templateData = {
Organisation: "Название организации",
User: "Тестовое Имя",
ifDBError: false,
Drivers: [],
Registrars: [],
};
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();
// Выполняем запрос для объединения данных из таблиц drivers и registrars
const queryDrivers = `
SELECT d.id, d.name, d.surname, d.transport, d.phone, d.email, d.card, r.connected
FROM drivers d
LEFT JOIN registrars r ON d.transport = r.serial
ORDER BY r.connected DESC NULLS LAST, CASE WHEN r.connected = true THEN 0 ELSE 1 END, d.id
`;
const driversResult = await client.query(queryDrivers);
templateData.Drivers = driversResult.rows.map((driver) => ({
id: driver.id,
name: driver.name,
surname: driver.surname,
transport: driver.transport,
phone: driver.phone,
email: driver.email,
card: driver.card,
}));
const queryRegistrars = `
SELECT serial
FROM registrars
`;
const registrarsResult = await client.query(queryRegistrars);
templateData.Registrars = registrarsResult.rows.map(
(registrar) => registrar.serial
);
console.log(templateData);
const source = fs.readFileSync(
"static/templates/devices/drivers.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
client.release();
} catch (error) {
console.error(error);
templateData.ifDBError = true;
const source = fs.readFileSync(
"static/templates/devices/drivers.html",
"utf8"
);
const template = handlebars.compile(source);
const resultT = template(templateData);
res.send(resultT);
}
2023-07-03 22:31:18 +00:00
}
2023-07-24 04:53:11 +00:00
function update(req, res) {
res.sendFile(path.join(__dirname, "static/templates/devices/update.html"));
}
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) => {
// res.sendFile(path.join(__dirname, "static/templates/404.html"));
// });