users permission upd, logo, live alarms upd
This commit is contained in:
		
							
								
								
									
										205
									
								
								server.js
									
									
									
									
									
								
							
							
						
						
									
										205
									
								
								server.js
									
									
									
									
									
								
							| @@ -81,6 +81,9 @@ async function getUserInfo(userId) { | |||||||
|       Organisation: "", |       Organisation: "", | ||||||
|       User: '', |       User: '', | ||||||
|       Users: [], |       Users: [], | ||||||
|  |       EditTransport: false, | ||||||
|  |       DeleteTransport: false, | ||||||
|  |       Update: false, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (userId != "admin") { |     if (userId != "admin") { | ||||||
| @@ -100,8 +103,14 @@ async function getUserInfo(userId) { | |||||||
|         update: user.update, |         update: user.update, | ||||||
|       }); |       }); | ||||||
|       userInfo.User = user.name + " " + user.surname; |       userInfo.User = user.name + " " + user.surname; | ||||||
|  |       userInfo.EditTransport = user.edittransport; | ||||||
|  |       userInfo.DeleteTransport = user.deletetransport; | ||||||
|  |       userInfo.Update = user.update; | ||||||
|     } else { |     } else { | ||||||
|       userInfo.User = "Администратор" |       userInfo.User = "Администратор" | ||||||
|  |       userInfo.EditTransport = true; | ||||||
|  |       userInfo.DeleteTransport = true; | ||||||
|  |       userInfo.Update = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const queryMain = `SELECT organisation FROM main`; |     const queryMain = `SELECT organisation FROM main`; | ||||||
| @@ -219,6 +228,21 @@ async function index(req, res) { | |||||||
|  |  | ||||||
|     templateData.Count = registrars.rows[0].count; |     templateData.Count = registrars.rows[0].count; | ||||||
|  |  | ||||||
|  |     let serialValues = []; | ||||||
|  |     if (!templateData.isAdmin) { | ||||||
|  |       const userDevicesQuery = ` | ||||||
|  |         SELECT devices | ||||||
|  |         FROM users | ||||||
|  |         WHERE id = $1 | ||||||
|  |       `; | ||||||
|  |       const userDevicesResult = await client.query(userDevicesQuery, [req.session.userId]); | ||||||
|  |        | ||||||
|  |       if (userDevicesResult.rows.length > 0) { | ||||||
|  |         serialValues = userDevicesResult.rows[0].devices; | ||||||
|  |       }  | ||||||
|  |       templateData.Count = serialValues.length; | ||||||
|  |     }  | ||||||
|  |  | ||||||
|     const last11DaysQuery = ` |     const last11DaysQuery = ` | ||||||
|     WITH date_sequence AS ( |     WITH date_sequence AS ( | ||||||
|       SELECT DATE_TRUNC('day', NOW() - INTERVAL '10 days' - INTERVAL '3 hours') + (generate_series(0, 10) || ' days')::interval AS day |       SELECT DATE_TRUNC('day', NOW() - INTERVAL '10 days' - INTERVAL '3 hours') + (generate_series(0, 10) || ' days')::interval AS day | ||||||
| @@ -233,14 +257,14 @@ async function index(req, res) { | |||||||
|       WHERE alarmtype = 56 |       WHERE alarmtype = 56 | ||||||
|       AND time >= NOW() - INTERVAL '11 days' + INTERVAL '3 hours' |       AND time >= NOW() - INTERVAL '11 days' + INTERVAL '3 hours' | ||||||
|       AND time <= NOW() + INTERVAL '1 day' + INTERVAL '3 hours' |       AND time <= NOW() + INTERVAL '1 day' + INTERVAL '3 hours' | ||||||
|  |       ${!templateData.isAdmin ? 'AND serial = ANY($1)' : ''} | ||||||
|       ORDER BY evtuuid, time DESC  |       ORDER BY evtuuid, time DESC  | ||||||
|       LIMIT 100 |       LIMIT 100 | ||||||
|     ) AS a ON DATE_TRUNC('day', a.time) = date_sequence.day |     ) AS a ON DATE_TRUNC('day', a.time) = date_sequence.day | ||||||
|     GROUP BY date_sequence.day |     GROUP BY date_sequence.day | ||||||
|     ORDER BY date_sequence.day DESC; |     ORDER BY date_sequence.day DESC; | ||||||
|      |  | ||||||
|     `; |     `; | ||||||
|     const last11DaysAlarms = await client.query(last11DaysQuery); |     const last11DaysAlarms = await client.query(last11DaysQuery, templateData.isAdmin ? [] : [serialValues]); | ||||||
|  |  | ||||||
|     const daysBeforeQuery = ` |     const daysBeforeQuery = ` | ||||||
|     WITH date_sequence AS ( |     WITH date_sequence AS ( | ||||||
| @@ -256,15 +280,15 @@ async function index(req, res) { | |||||||
|       WHERE alarmtype = 56 |       WHERE alarmtype = 56 | ||||||
|       AND time >= NOW() - INTERVAL '21 days' + INTERVAL '3 hours' |       AND time >= NOW() - INTERVAL '21 days' + INTERVAL '3 hours' | ||||||
|       AND time <= NOW() + INTERVAL '10 day' + INTERVAL '3 hours' |       AND time <= NOW() + INTERVAL '10 day' + INTERVAL '3 hours' | ||||||
|  |       ${!templateData.isAdmin ? 'AND serial = ANY($1)' : ''} | ||||||
|       ORDER BY evtuuid, time DESC  |       ORDER BY evtuuid, time DESC  | ||||||
|       LIMIT 100 |       LIMIT 100 | ||||||
|     ) AS a ON DATE_TRUNC('day', a.time) = date_sequence.day |     ) AS a ON DATE_TRUNC('day', a.time) = date_sequence.day | ||||||
|     GROUP BY date_sequence.day |     GROUP BY date_sequence.day | ||||||
|     ORDER BY date_sequence.day DESC; |     ORDER BY date_sequence.day DESC; | ||||||
|            |  | ||||||
|     `; |     `; | ||||||
|  |  | ||||||
|     const daysBeforeAlarms = await client.query(daysBeforeQuery); |     const daysBeforeAlarms = await client.query(daysBeforeQuery, templateData.isAdmin ? [] : [serialValues]); | ||||||
|  |  | ||||||
|     const currentDate = new Date(); |     const currentDate = new Date(); | ||||||
|     const dates = []; |     const dates = []; | ||||||
| @@ -289,10 +313,13 @@ async function index(req, res) { | |||||||
|   FROM geo |   FROM geo | ||||||
|   WHERE time >= NOW() - INTERVAL '10 days' + INTERVAL '3 hours' |   WHERE time >= NOW() - INTERVAL '10 days' + INTERVAL '3 hours' | ||||||
|     AND time <= NOW() + INTERVAL '1 day' + INTERVAL '3 hours' |     AND time <= NOW() + INTERVAL '1 day' + INTERVAL '3 hours' | ||||||
|  |     ${!templateData.isAdmin ? 'AND serial = ANY($1)' : ''} | ||||||
|   GROUP BY DATE_TRUNC('day', time) |   GROUP BY DATE_TRUNC('day', time) | ||||||
|   ORDER BY sort_value DESC, day DESC |   ORDER BY sort_value DESC, day DESC; | ||||||
| `; | `; | ||||||
|     const positionsLast11Days = await client.query(positionsLast11DaysQuery); |  | ||||||
|  | const positionsLast11Days = await client.query(positionsLast11DaysQuery, templateData.isAdmin ? [] : [serialValues]); | ||||||
|  |  | ||||||
|  |  | ||||||
|     templateData.Dates.reverse(); |     templateData.Dates.reverse(); | ||||||
|  |  | ||||||
| @@ -513,10 +540,25 @@ async function live(req, res) { | |||||||
|  |  | ||||||
|     const minuteInMillis = 90 * 1000; |     const minuteInMillis = 90 * 1000; | ||||||
|  |  | ||||||
|     const query = ` |     let serialValues = []; | ||||||
|     SELECT id, serial, channels, lastkeepalive FROM registrars ORDER BY id ASC |     if (!templateData.isAdmin) { | ||||||
|  |        | ||||||
|  |       const userDevicesQuery = ` | ||||||
|  |         SELECT devices | ||||||
|  |         FROM users | ||||||
|  |         WHERE id = $1 | ||||||
|       `; |       `; | ||||||
|     const registrars = await client.query(query); |       const userDevicesResult = await client.query(userDevicesQuery, [req.session.userId]); | ||||||
|  |        | ||||||
|  |       if (userDevicesResult.rows.length > 0) { | ||||||
|  |         serialValues = userDevicesResult.rows[0].devices; | ||||||
|  |       }  | ||||||
|  |     }  | ||||||
|  |  | ||||||
|  |     const query = ` | ||||||
|  |     SELECT id, serial, channels, lastkeepalive FROM registrars ${!templateData.isAdmin ? 'WHERE serial = ANY($1)' : ''} ORDER BY id ASC | ||||||
|  |     `; | ||||||
|  |     const registrars = await client.query(query, templateData.isAdmin ? [] : [serialValues]); | ||||||
|  |  | ||||||
|     templateData.Registrars = registrars.rows.map((row) => ({ |     templateData.Registrars = registrars.rows.map((row) => ({ | ||||||
|       id: row.id, |       id: row.id, | ||||||
| @@ -531,6 +573,7 @@ async function live(req, res) { | |||||||
|       SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st |       SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st | ||||||
|       FROM alarms |       FROM alarms | ||||||
|       WHERE alarmtype = 56 |       WHERE alarmtype = 56 | ||||||
|  |       ${!templateData.isAdmin ? 'AND serial = ANY($2)' : ''} | ||||||
|       ORDER BY evtuuid, time DESC  |       ORDER BY evtuuid, time DESC  | ||||||
|       LIMIT 100 |       LIMIT 100 | ||||||
|     ) AS a |     ) AS a | ||||||
| @@ -542,7 +585,7 @@ async function live(req, res) { | |||||||
|     ) AS g ON a.serial = g.serial AND g.row_num = 1 |     ) AS g ON a.serial = g.serial AND g.row_num = 1 | ||||||
|     ORDER BY a.time DESC; |     ORDER BY a.time DESC; | ||||||
|     `; |     `; | ||||||
|     const alarms = await client.query(subquery, [new Date()]);  |     const alarms = await client.query(subquery, templateData.isAdmin ? [new Date()] : [new Date(), serialValues]);  | ||||||
|  |  | ||||||
|     function formatDate(date) { |     function formatDate(date) { | ||||||
|       const options = { |       const options = { | ||||||
| @@ -629,7 +672,7 @@ async function live(req, res) { | |||||||
|           type = "!! Управление одной рукой"; |           type = "!! Управление одной рукой"; | ||||||
|           break; |           break; | ||||||
|         case "22": |         case "22": | ||||||
|           type = "Очки, блокирующие инфракрасное излучение"; |           type = "Очки, блокирующие инфракрасное"; | ||||||
|           break; |           break; | ||||||
|         case "23": |         case "23": | ||||||
|           type = "Слепые зоны слева"; |           type = "Слепые зоны слева"; | ||||||
| @@ -687,10 +730,10 @@ async function live(req, res) { | |||||||
|     // Выполняем запрос, чтобы получить все данные из таблицы registrars |     // Выполняем запрос, чтобы получить все данные из таблицы registrars | ||||||
|     const queryRegistrars = ` |     const queryRegistrars = ` | ||||||
|       SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port |       SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port | ||||||
|       FROM registrars |       FROM registrars ${!templateData.isAdmin ? 'WHERE serial = ANY($1)' : ''} | ||||||
|       ORDER BY id |       ORDER BY id | ||||||
|     `; |     `; | ||||||
|     const registrarsResult = await client.query(queryRegistrars); |     const registrarsResult = await client.query(queryRegistrars, templateData.isAdmin ? [] : [serialValues]); | ||||||
|     const allRegistrars = registrarsResult.rows; |     const allRegistrars = registrarsResult.rows; | ||||||
|  |  | ||||||
|     const groupedRegistrars = {}; |     const groupedRegistrars = {}; | ||||||
| @@ -839,12 +882,28 @@ async function reports(req, res) { | |||||||
|     }); |     }); | ||||||
|     const client = await pool.connect(); |     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]); | ||||||
|  |        | ||||||
|  |       if (userDevicesResult.rows.length > 0) { | ||||||
|  |         serialValues = userDevicesResult.rows[0].devices; | ||||||
|  |       }  | ||||||
|  |     }  | ||||||
|  |  | ||||||
|     const query = ` |     const query = ` | ||||||
|     SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude |     SELECT a.evtuuid, a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude | ||||||
|     FROM ( |     FROM ( | ||||||
|       SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st |       SELECT DISTINCT ON (evtuuid) evtuuid, id, cmdno, time, serial, st | ||||||
|       FROM alarms |       FROM alarms | ||||||
|       WHERE alarmtype = 56 |       WHERE alarmtype = 56 | ||||||
|  |       ${!templateData.isAdmin ? 'AND serial = ANY($2)' : ''} | ||||||
|       ORDER BY evtuuid, time DESC  |       ORDER BY evtuuid, time DESC  | ||||||
|       LIMIT 100 |       LIMIT 100 | ||||||
|     ) AS a |     ) AS a | ||||||
| @@ -856,7 +915,7 @@ async function reports(req, res) { | |||||||
|     ) AS g ON a.serial = g.serial AND g.row_num = 1 |     ) AS g ON a.serial = g.serial AND g.row_num = 1 | ||||||
|     ORDER BY a.time DESC; |     ORDER BY a.time DESC; | ||||||
|     `; |     `; | ||||||
|     const alarms = await client.query(query, [new Date()]);  |     const alarms = await client.query(query, templateData.isAdmin ? [new Date()] : [new Date(), serialValues]);  | ||||||
|  |  | ||||||
|     function formatDate(date) { |     function formatDate(date) { | ||||||
|       const options = { |       const options = { | ||||||
| @@ -999,10 +1058,10 @@ async function reports(req, res) { | |||||||
|     // Выполняем запрос, чтобы получить все данные из таблицы registrars |     // Выполняем запрос, чтобы получить все данные из таблицы registrars | ||||||
|     const queryRegistrars = ` |     const queryRegistrars = ` | ||||||
|       SELECT id, serial, lastkeepalive, "group", name, plate, sim, ip, port |       SELECT id, serial, lastkeepalive, "group", name, plate, sim, ip, port | ||||||
|       FROM registrars |       FROM registrars ${!templateData.isAdmin ? 'WHERE serial = ANY($1)' : ''} | ||||||
|       ORDER BY id |       ORDER BY id | ||||||
|     `; |     `; | ||||||
|     const registrarsResult = await client.query(queryRegistrars); |     const registrarsResult = await client.query(queryRegistrars, templateData.isAdmin ? [] : [serialValues]); | ||||||
|     const allRegistrars = registrarsResult.rows; |     const allRegistrars = registrarsResult.rows; | ||||||
|  |  | ||||||
|     const groupedRegistrars = {}; |     const groupedRegistrars = {}; | ||||||
| @@ -1057,11 +1116,26 @@ app.get("/api/devices", async (req, res) => { | |||||||
|     const { page = 1, limit = 10 } = req.query; |     const { page = 1, limit = 10 } = req.query; | ||||||
|     const offset = (page - 1) * limit; |     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]); | ||||||
|  |        | ||||||
|  |       if (userDevicesResult.rows.length > 0) { | ||||||
|  |         serialValues = userDevicesResult.rows[0].devices; | ||||||
|  |       }  | ||||||
|  |     }  | ||||||
|  |  | ||||||
|     const query = ` |     const query = ` | ||||||
|       SELECT a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude |       SELECT a.id, a.cmdno, a.time, a.serial, a.st, r.plate, g.latitude, g.longitude | ||||||
|       FROM ( |       FROM ( | ||||||
|         SELECT id, cmdno, time, serial, st |         SELECT id, cmdno, time, serial, st | ||||||
|         FROM alarms |         FROM alarms | ||||||
|  |         ${!templateData.isAdmin ? 'WHERE serial = ANY($4)' : ''} | ||||||
|         ORDER BY time DESC  |         ORDER BY time DESC  | ||||||
|         LIMIT $1 OFFSET $2 |         LIMIT $1 OFFSET $2 | ||||||
|       ) AS a |       ) AS a | ||||||
| @@ -1073,7 +1147,7 @@ app.get("/api/devices", async (req, res) => { | |||||||
|       ) AS g ON a.serial = g.serial AND g.row_num = 1 |       ) AS g ON a.serial = g.serial AND g.row_num = 1 | ||||||
|       ORDER BY a.time DESC; |       ORDER BY a.time DESC; | ||||||
|     `; |     `; | ||||||
|     const alarms = await pool.query(query, [limit, offset, new Date()]);  |     const alarms = await pool.query(query, templateData.isAdmin ? [limit, offset, new Date()] : [limit, offset, new Date(), serialValues]);  | ||||||
|  |  | ||||||
|     function formatDate(date) { |     function formatDate(date) { | ||||||
|       const options = { |       const options = { | ||||||
| @@ -1119,8 +1193,8 @@ app.get("/api/devices", async (req, res) => { | |||||||
|       }; |       }; | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     const totalCountQuery = "SELECT COUNT(*) FROM alarms;"; |     const totalCountQuery = `SELECT COUNT(*) FROM alarms ${!templateData.isAdmin ? 'WHERE serial = ANY($1)' : ''};`; | ||||||
|     const totalCount = await pool.query(totalCountQuery); |     const totalCount = await pool.query(totalCountQuery, templateData.isAdmin ? [] : [serialValues]); | ||||||
|  |  | ||||||
|     const totalPages = Math.ceil(totalCount.rows[0].count / limit); |     const totalPages = Math.ceil(totalCount.rows[0].count / limit); | ||||||
|  |  | ||||||
| @@ -1216,6 +1290,20 @@ app.get('/reports/:id', async (req, res) => { | |||||||
|    |    | ||||||
|     const minuteInMillis = 90 * 1000;  |     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]); | ||||||
|  |        | ||||||
|  |       if (userDevicesResult.rows.length > 0) { | ||||||
|  |         serialValues = userDevicesResult.rows[0].devices; | ||||||
|  |       }  | ||||||
|  |     }  | ||||||
|  |    | ||||||
|     const query = ` |     const query = ` | ||||||
|     WITH PrevNextGeo AS ( |     WITH PrevNextGeo AS ( | ||||||
|       SELECT |       SELECT | ||||||
| @@ -1408,6 +1496,8 @@ app.get('/reports/:id', async (req, res) => { | |||||||
|         actualSpeed = alarm.speed |         actualSpeed = alarm.speed | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       if (serialValues.includes(alarm.serial)) { | ||||||
|  |  | ||||||
|       templateData.Type = type; |       templateData.Type = type; | ||||||
|       templateData.Speed = actualSpeed; |       templateData.Speed = actualSpeed; | ||||||
|       templateData.Date = formatDate(alarm.time); |       templateData.Date = formatDate(alarm.time); | ||||||
| @@ -1437,7 +1527,10 @@ app.get('/reports/:id', async (req, res) => { | |||||||
|           return speed; |           return speed; | ||||||
|         } |         } | ||||||
|       }); |       }); | ||||||
|        |     } else { | ||||||
|  |       console.log("Нет доступа к данному аларму") | ||||||
|  |       templateData.ifDBError = true; | ||||||
|  |     } | ||||||
|     // console.log(templateData); |     // console.log(templateData); | ||||||
|    |    | ||||||
|     const source = fs.readFileSync("static/templates/reports/report.html", "utf8"); |     const source = fs.readFileSync("static/templates/reports/report.html", "utf8"); | ||||||
| @@ -1745,6 +1838,9 @@ async function devices(req, res) { | |||||||
|     Registrars: [], |     Registrars: [], | ||||||
|     Groups: [], |     Groups: [], | ||||||
|     GroupsList: [], |     GroupsList: [], | ||||||
|  |     EditTransport: false, | ||||||
|  |     DeleteTransport: false, | ||||||
|  |     Update: false, | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
| @@ -1757,6 +1853,20 @@ async function devices(req, res) { | |||||||
|     }); |     }); | ||||||
|     const client = await pool.connect(); |     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]); | ||||||
|  |        | ||||||
|  |       if (userDevicesResult.rows.length > 0) { | ||||||
|  |         serialValues = userDevicesResult.rows[0].devices; | ||||||
|  |       }  | ||||||
|  |     }  | ||||||
|  |  | ||||||
|     const groupsQuery = "SELECT id, name FROM groups"; |     const groupsQuery = "SELECT id, name FROM groups"; | ||||||
|     const groupsResult = await client.query(groupsQuery); |     const groupsResult = await client.query(groupsQuery); | ||||||
|     const groupsMap = {}; |     const groupsMap = {}; | ||||||
| @@ -1768,10 +1878,10 @@ async function devices(req, res) { | |||||||
|  |  | ||||||
|     const queryRegistrars = ` |     const queryRegistrars = ` | ||||||
|       SELECT id, serial, lastkeepalive, "group", name, plate, sim, ip, port |       SELECT id, serial, lastkeepalive, "group", name, plate, sim, ip, port | ||||||
|       FROM registrars |       FROM registrars ${!templateData.isAdmin ? 'WHERE serial = ANY($1)' : ''} | ||||||
|       ORDER BY id |       ORDER BY id | ||||||
|     `; |     `; | ||||||
|     const registrarsResult = await client.query(queryRegistrars); |     const registrarsResult = await client.query(queryRegistrars, templateData.isAdmin ? [] : [serialValues]); | ||||||
|     const allRegistrars = registrarsResult.rows; |     const allRegistrars = registrarsResult.rows; | ||||||
|  |  | ||||||
|     const groupedRegistrars = {}; |     const groupedRegistrars = {}; | ||||||
| @@ -1789,6 +1899,9 @@ async function devices(req, res) { | |||||||
|       Organisation: userInfo.Organisation, |       Organisation: userInfo.Organisation, | ||||||
|       User: userInfo.User, |       User: userInfo.User, | ||||||
|       UserInfo: userInfo.Users, |       UserInfo: userInfo.Users, | ||||||
|  |       EditTransport: userInfo.EditTransport, | ||||||
|  |       DeleteTransport: userInfo.DeleteTransport, | ||||||
|  |       Update: userInfo.Update, | ||||||
|       isAdmin: req.session.userId === 'admin', |       isAdmin: req.session.userId === 'admin', | ||||||
|       ifDBError: false, |       ifDBError: false, | ||||||
|       Registrars: allRegistrars.map((registrar) => ({ |       Registrars: allRegistrars.map((registrar) => ({ | ||||||
| @@ -1840,6 +1953,9 @@ async function groups(req, res) { | |||||||
|     return res.redirect("/signin"); |     return res.redirect("/signin"); | ||||||
|   } |   } | ||||||
|   const userInfo = await getUserInfo(req.session.userId); |   const userInfo = await getUserInfo(req.session.userId); | ||||||
|  |   if (!userInfo.EditTransport) { | ||||||
|  |     return res.redirect("/signin"); | ||||||
|  |   } | ||||||
|   let templateData = { |   let templateData = { | ||||||
|     Organisation: userInfo.Organisation, |     Organisation: userInfo.Organisation, | ||||||
|     User: userInfo.User, |     User: userInfo.User, | ||||||
| @@ -1847,6 +1963,9 @@ async function groups(req, res) { | |||||||
|     UserInfo: userInfo.Users, |     UserInfo: userInfo.Users, | ||||||
|     isAdmin: req.session.userId === 'admin', |     isAdmin: req.session.userId === 'admin', | ||||||
|     Groups: [], |     Groups: [], | ||||||
|  |     EditTransport: userInfo.EditTransport, | ||||||
|  |     DeleteTransport: userInfo.DeleteTransport, | ||||||
|  |     Update: userInfo.Update, | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
| @@ -2635,12 +2754,18 @@ async function update(req, res) { | |||||||
|     return res.redirect("/signin"); |     return res.redirect("/signin"); | ||||||
|   } |   } | ||||||
|   const userInfo = await getUserInfo(req.session.userId); |   const userInfo = await getUserInfo(req.session.userId); | ||||||
|  |   if (!userInfo.Update) { | ||||||
|  |     return res.redirect("/signin"); | ||||||
|  |   } | ||||||
|   let templateData = { |   let templateData = { | ||||||
|     Organisation: userInfo.Organisation, |     Organisation: userInfo.Organisation, | ||||||
|     User: userInfo.User, |     User: userInfo.User, | ||||||
|     ifDBError: false, |     ifDBError: false, | ||||||
|     UserInfo: userInfo.Users, |     UserInfo: userInfo.Users, | ||||||
|     isAdmin: req.session.userId === 'admin', |     isAdmin: req.session.userId === 'admin', | ||||||
|  |     EditTransport: userInfo.EditTransport, | ||||||
|  |     DeleteTransport: userInfo.DeleteTransport, | ||||||
|  |     Update: userInfo.Update, | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
| @@ -3093,6 +3218,20 @@ async function videos(req, res) { | |||||||
|     }); |     }); | ||||||
|     const client = await pool.connect(); |     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]); | ||||||
|  |        | ||||||
|  |       if (userDevicesResult.rows.length > 0) { | ||||||
|  |         serialValues = userDevicesResult.rows[0].devices; | ||||||
|  |       }  | ||||||
|  |     }  | ||||||
|  |  | ||||||
|     const minuteInMillis = 60 * 1000; |     const minuteInMillis = 60 * 1000; | ||||||
|  |  | ||||||
|     // Получаем список групп и их идентификаторов из таблицы groups |     // Получаем список групп и их идентификаторов из таблицы groups | ||||||
| @@ -3107,10 +3246,10 @@ async function videos(req, res) { | |||||||
|     // Выполняем запрос, чтобы получить все данные из таблицы registrars |     // Выполняем запрос, чтобы получить все данные из таблицы registrars | ||||||
|     const queryRegistrars = ` |     const queryRegistrars = ` | ||||||
|       SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port |       SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port | ||||||
|       FROM registrars |       FROM registrars ${!templateData.isAdmin ? 'WHERE serial = ANY($1)' : ''} | ||||||
|       ORDER BY id |       ORDER BY id | ||||||
|     `; |     `; | ||||||
|     const registrarsResult = await client.query(queryRegistrars); |     const registrarsResult = await client.query(queryRegistrars, templateData.isAdmin ? [] : [serialValues]); | ||||||
|     const allRegistrars = registrarsResult.rows; |     const allRegistrars = registrarsResult.rows; | ||||||
|  |  | ||||||
|     const groupedRegistrars = {}; |     const groupedRegistrars = {}; | ||||||
| @@ -3195,6 +3334,20 @@ async function videoExport(req, res) { | |||||||
|     }); |     }); | ||||||
|     const client = await pool.connect(); |     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]); | ||||||
|  |        | ||||||
|  |       if (userDevicesResult.rows.length > 0) { | ||||||
|  |         serialValues = userDevicesResult.rows[0].devices; | ||||||
|  |       }  | ||||||
|  |     }  | ||||||
|  |  | ||||||
|     const minuteInMillis = 60 * 1000; |     const minuteInMillis = 60 * 1000; | ||||||
|  |  | ||||||
|      // Получаем список групп и их идентификаторов из таблицы groups |      // Получаем список групп и их идентификаторов из таблицы groups | ||||||
| @@ -3209,10 +3362,10 @@ async function videoExport(req, res) { | |||||||
|      // Выполняем запрос, чтобы получить все данные из таблицы registrars |      // Выполняем запрос, чтобы получить все данные из таблицы registrars | ||||||
|      const queryRegistrars = ` |      const queryRegistrars = ` | ||||||
|        SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port |        SELECT id, serial, channels, lastkeepalive, "group", name, plate, sim, ip, port | ||||||
|        FROM registrars |        FROM registrars ${!templateData.isAdmin ? 'WHERE serial = ANY($1)' : ''} | ||||||
|        ORDER BY id |        ORDER BY id | ||||||
|      `; |      `; | ||||||
|      const registrarsResult = await client.query(queryRegistrars); |      const registrarsResult = await client.query(queryRegistrars, templateData.isAdmin ? [] : [serialValues]); | ||||||
|      const allRegistrars = registrarsResult.rows; |      const allRegistrars = registrarsResult.rows; | ||||||
|   |   | ||||||
|      const groupedRegistrars = {}; |      const groupedRegistrars = {}; | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								static/img/argus.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/img/argus.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 107 KiB | 
							
								
								
									
										
											BIN
										
									
								
								static/img/argus5.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/img/argus5.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 95 KiB | 
| @@ -54,6 +54,7 @@ var positionsOptions = { | |||||||
|       ticks: { |       ticks: { | ||||||
|         stepSize: 10000, |         stepSize: 10000, | ||||||
|       }, |       }, | ||||||
|  |       beginAtZero: true, | ||||||
|     }, |     }, | ||||||
|     x: { |     x: { | ||||||
|       grid: { |       grid: { | ||||||
|   | |||||||
| @@ -70,18 +70,21 @@ const createTable = () => { | |||||||
|     // Добавляем кнопку удаления после каждого ряда |     // Добавляем кнопку удаления после каждого ряда | ||||||
|     const trashCell = document.createElement("td"); |     const trashCell = document.createElement("td"); | ||||||
|     trashCell.setAttribute("class", "optionsCell"); |     trashCell.setAttribute("class", "optionsCell"); | ||||||
|  |     if (DeleteTransport) { | ||||||
|     const trashButton = document.createElement("button"); |     const trashButton = document.createElement("button"); | ||||||
|     trashButton.setAttribute("class", "trash"); |     trashButton.setAttribute("class", "trash"); | ||||||
|     trashButton.value = `delete-device-${device.id}`; |     trashButton.value = `delete-device-${device.id}`; | ||||||
|     trashButton.id = `delete-device-${device.id}`; |     trashButton.id = `delete-device-${device.id}`; | ||||||
|  |     trashCell.appendChild(trashButton); | ||||||
|  |     } | ||||||
|  |     if (EditTransport) { | ||||||
|     const optionsButton = document.createElement("button"); |     const optionsButton = document.createElement("button"); | ||||||
|     optionsButton.setAttribute("class", "options"); |     optionsButton.setAttribute("class", "options"); | ||||||
|     optionsButton.setAttribute("onclick", `openForm("${device.id}")`); |     optionsButton.setAttribute("onclick", `openForm("${device.id}")`); | ||||||
|     optionsButton.value = `options-device-${device.id}`; |     optionsButton.value = `options-device-${device.id}`; | ||||||
|     optionsButton.id = `options-device-${device.id}`; |     optionsButton.id = `options-device-${device.id}`; | ||||||
|  |  | ||||||
|     trashCell.appendChild(optionsButton); |     trashCell.appendChild(optionsButton); | ||||||
|     trashCell.appendChild(trashButton); |     } | ||||||
|  |  | ||||||
|     row.appendChild(trashCell); |     row.appendChild(trashCell); | ||||||
|     tbody.appendChild(row); |     tbody.appendChild(row); | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ header h1 { | |||||||
|   color: rgba(0, 0, 0, 0.75); |   color: rgba(0, 0, 0, 0.75); | ||||||
|   font-weight: 700; |   font-weight: 700; | ||||||
|   font-size: 30px; |   font-size: 30px; | ||||||
|   margin-left: 45px; |   margin-left: 15px; | ||||||
|   margin-right: 35px; |   margin-right: 35px; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -51,6 +51,11 @@ header h2 span { | |||||||
|   margin-right: 7px; |   margin-right: 7px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | header img { | ||||||
|  |   height: 36px; | ||||||
|  |   margin-left: 15px; | ||||||
|  | } | ||||||
|  |  | ||||||
| .account-info { | .account-info { | ||||||
|   color: rgba(0, 0, 0, 0.75); |   color: rgba(0, 0, 0, 0.75); | ||||||
|   /* margin: 0 5px 0 auto; */ |   /* margin: 0 5px 0 auto; */ | ||||||
| @@ -213,6 +218,7 @@ header h2 span { | |||||||
| .main .bg { | .main .bg { | ||||||
|   margin-top: 12px; |   margin-top: 12px; | ||||||
|   background-color: #fcfcff; |   background-color: #fcfcff; | ||||||
|  |   background: repeat center url(../img/argus5.png); | ||||||
|   border-top: 2px solid #f5f5fa; |   border-top: 2px solid #f5f5fa; | ||||||
|   min-height: calc(100vh - 162px - 128px); |   min-height: calc(100vh - 162px - 128px); | ||||||
|   /* height: fit-content; */ |   /* height: fit-content; */ | ||||||
| @@ -965,7 +971,7 @@ tr:nth-child(even) { | |||||||
|   display: flex; |   display: flex; | ||||||
|   align-items: center; |   align-items: center; | ||||||
|   justify-content: center; |   justify-content: center; | ||||||
|   background: no-repeat center url(../img/griphon.png); |   background: no-repeat center url(../img/argus5.png); | ||||||
|   background-size: cover; |   background-size: cover; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1896,7 +1902,7 @@ input[type="datetime-local"] { | |||||||
|   border: 1px solid rgba(0, 0, 0, 0.1); |   border: 1px solid rgba(0, 0, 0, 0.1); | ||||||
|   border-radius: 10px; |   border-radius: 10px; | ||||||
|   display: inline-block; |   display: inline-block; | ||||||
|   margin: 10px 0 0 20px; |   margin: 5px 0 0 20px; | ||||||
|   width: 307px; |   width: 307px; | ||||||
|   cursor: pointer; |   cursor: pointer; | ||||||
|   transition: 0.2s; |   transition: 0.2s; | ||||||
| @@ -1939,8 +1945,16 @@ input[type="datetime-local"] { | |||||||
|  |  | ||||||
| .signals-list label p.name { | .signals-list label p.name { | ||||||
|   float: left; |   float: left; | ||||||
|   width: fit-content; |   /* width: fit-content; */ | ||||||
|   margin: 10px 0 12px 10px; |   margin: 10px 0 10px 10px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .signals-list label p.name:first-child { | ||||||
|  |   margin-bottom: 3px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .signals-list label p.name:last-child { | ||||||
|  |   margin-top: 3px; | ||||||
| } | } | ||||||
|  |  | ||||||
| .signals-list label p.name svg { | .signals-list label p.name svg { | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
| @@ -43,9 +44,11 @@ | |||||||
|         <a href="/videos"> |         <a href="/videos"> | ||||||
|             <div><img src="../../img/play.svg">Записи</div> |             <div><img src="../../img/play.svg">Записи</div> | ||||||
|         </a> |         </a> | ||||||
|  |         {{#if isAdmin}} | ||||||
|         <a class="admin-panel" href="/admin"> |         <a class="admin-panel" href="/admin"> | ||||||
|           <div><img src="../../img/keyboard.svg">Админка</div> |             <div><img src="../img/keyboard.svg">Админка</div> | ||||||
|         </a> |         </a> | ||||||
|  |         {{/if}} | ||||||
|         <a class="settings" href="/settings"> |         <a class="settings" href="/settings"> | ||||||
|             <div><img src="../../img/gear.svg">Настройки</div> |             <div><img src="../../img/gear.svg">Настройки</div> | ||||||
|         </a> |         </a> | ||||||
| @@ -100,7 +103,9 @@ | |||||||
|     <a href="/devices">Список устройств</a> |     <a href="/devices">Список устройств</a> | ||||||
|     <a class="selected" href="/devices/groups">Группы</a> |     <a class="selected" href="/devices/groups">Группы</a> | ||||||
|  |  | ||||||
|  |     {{#if Update}} | ||||||
|     <a class="update" href="/devices/update">Обновление ПО</a> |     <a class="update" href="/devices/update">Обновление ПО</a> | ||||||
|  |     {{/if}} | ||||||
|   </nav> |   </nav> | ||||||
|         <section class="bg"> |         <section class="bg"> | ||||||
|             <section class="content"> |             <section class="content"> | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
| @@ -69,12 +70,16 @@ | |||||||
|         </div> |         </div> | ||||||
|         <nav> |         <nav> | ||||||
|             <a class="selected" href="/devices">Список устройств</a> |             <a class="selected" href="/devices">Список устройств</a> | ||||||
|  |             {{#if EditTransport}} | ||||||
|             <a href="/devices/groups">Группы</a> |             <a href="/devices/groups">Группы</a> | ||||||
|  |             {{/if}} | ||||||
|             <!-- <a href="/devices/drivers">Водители</a> --> |             <!-- <a href="/devices/drivers">Водители</a> --> | ||||||
|             <!-- <a href="/devices/newdevice">Добавить устройство</a> --> |             <!-- <a href="/devices/newdevice">Добавить устройство</a> --> | ||||||
|             <!-- <a href="/devices/newdriver">Добавить водителя</a> --> |             <!-- <a href="/devices/newdriver">Добавить водителя</a> --> | ||||||
|  |  | ||||||
|  |             {{#if Update}} | ||||||
|             <a class="update" href="/devices/update">Обновление ПО</a> |             <a class="update" href="/devices/update">Обновление ПО</a> | ||||||
|  |             {{/if}} | ||||||
|         </nav> |         </nav> | ||||||
|         <section class="bg"> |         <section class="bg"> | ||||||
|             <section class="content"> |             <section class="content"> | ||||||
| @@ -116,7 +121,9 @@ | |||||||
|                                 <th>Номер SIM-карты</th> |                                 <th>Номер SIM-карты</th> | ||||||
|                                 <th>IP-адрес</th> |                                 <th>IP-адрес</th> | ||||||
|                                 <th>Порт</th> |                                 <th>Порт</th> | ||||||
|                                 <th><button id="delete-device-all" value="delete-device-all" class="trash"></button></th> |                                 <th>{{#if DeleteTransport}} | ||||||
|  |                                   <button id="delete-device-all" value="delete-device-all" class="trash"></button> | ||||||
|  |                                   {{/if}}</th> | ||||||
|                               </tr> |                               </tr> | ||||||
|                             </thead> |                             </thead> | ||||||
|                             <tbody> |                             <tbody> | ||||||
| @@ -523,6 +530,15 @@ | |||||||
|   }, |   }, | ||||||
|   {{/each}} |   {{/each}} | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
|  |       let EditTransport = false; | ||||||
|  |       {{#if EditTransport}} | ||||||
|  |       EditTransport = true; | ||||||
|  |       {{/if}} | ||||||
|  |       let DeleteTransport = false; | ||||||
|  |       {{#if DeleteTransport}} | ||||||
|  |       DeleteTransport = true; | ||||||
|  |       {{/if}} | ||||||
|     </script> |     </script> | ||||||
|  |  | ||||||
|     <script src="../scripts/table.js"></script> |     <script src="../scripts/table.js"></script> | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
| @@ -59,7 +60,9 @@ | |||||||
|         </div> |         </div> | ||||||
|         <nav> |         <nav> | ||||||
|             <a href="/devices">Список устройств</a> |             <a href="/devices">Список устройств</a> | ||||||
|  |             {{#if EditTransport}} | ||||||
|             <a href="/devices/groups">Группы</a> |             <a href="/devices/groups">Группы</a> | ||||||
|  |             {{/if}} | ||||||
|             <!-- <a href="/devices/drivers">Водители</a> --> |             <!-- <a href="/devices/drivers">Водители</a> --> | ||||||
|             <!-- <a href="/devices/newdevice">Добавить устройство</a> --> |             <!-- <a href="/devices/newdevice">Добавить устройство</a> --> | ||||||
|             <!-- <a href="/devices/newdriver">Добавить водителя</a> --> |             <!-- <a href="/devices/newdriver">Добавить водителя</a> --> | ||||||
|   | |||||||
| @@ -9,9 +9,16 @@ | |||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
|  |  | ||||||
|  |     <style> | ||||||
|  |         .main .bg { | ||||||
|  |             min-height: calc(100vh - 162px - 92px) !important; | ||||||
|  |         } | ||||||
|  |     </style> | ||||||
|  |  | ||||||
|     <div class="page-transition"></div> |     <div class="page-transition"></div> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ | |||||||
|    |    | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
| @@ -72,7 +73,7 @@ | |||||||
|             <span>Прямые трансляции</span> |             <span>Прямые трансляции</span> | ||||||
|         </div> |         </div> | ||||||
|         <nav> |         <nav> | ||||||
|             <a class="selected" href="/live">Просмотр</a> |             <a class="selected" href="/live">Отслеживание</a> | ||||||
|         </nav> |         </nav> | ||||||
|         <section class="bg"> |         <section class="bg"> | ||||||
|             <section class="content"> |             <section class="content"> | ||||||
| @@ -123,10 +124,7 @@ | |||||||
|                     <section class="table" style="position: relative;"> |                     <section class="table" style="position: relative;"> | ||||||
|                       <div id="signals-list" class="signals-list"> |                       <div id="signals-list" class="signals-list"> | ||||||
|                         <h1>Сигналы ТС</h1> |                         <h1>Сигналы ТС</h1> | ||||||
|                         <svg id="left-slider" class="left-slider" xmlns="http://www.w3.org/2000/svg" width="19" height="19" fill="none" viewBox="0 0 11 19"> |                         <!-- <input class="search" type="text" placeholder="Поиск"> --> | ||||||
|                           <path fill="#000" fill-opacity=".75" d="M0 9.495c0 .273.101.514.315.722l8.92 8.477a.981.981 0 0 0 .73.295c.585 0 1.035-.427 1.035-.995 0-.285-.124-.525-.304-.711L2.508 9.495l8.188-7.789c.18-.186.304-.437.304-.71C11 .425 10.55 0 9.965 0c-.292 0-.54.098-.73.284L.314 8.773A.955.955 0 0 0 0 9.495Z"/> |  | ||||||
|                         </svg> |  | ||||||
|                         <input class="search" type="text" placeholder="Поиск"> |  | ||||||
|  |  | ||||||
|                         <ul id="list"> |                         <ul id="list"> | ||||||
|                           {{#each Alarms}} |                           {{#each Alarms}} | ||||||
| @@ -134,17 +132,20 @@ | |||||||
|                             <!-- <input type="radio" name="signal" id="signal-{{this.id}}" hidden> --> |                             <!-- <input type="radio" name="signal" id="signal-{{this.id}}" hidden> --> | ||||||
|                             <a style="color:rgba(0, 0, 0, 0.7);" href="/reports/{{this.id}}" target="_blank"> |                             <a style="color:rgba(0, 0, 0, 0.7);" href="/reports/{{this.id}}" target="_blank"> | ||||||
|                             <label for="signal-{{this.id}}"> |                             <label for="signal-{{this.id}}"> | ||||||
|                               <h2>{{this.type}}</h2> |                               <!-- <h2>{{this.type}}</h2> --> | ||||||
|                               <span>ID {{this.id}}</span> |                               <!-- <span>ID {{this.id}}</span> --> | ||||||
|                               <p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14"> |                               <!-- <p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 14 14"> | ||||||
|                                 <path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/> |                                 <path fill="#000" fill-opacity=".75" d="M3.41 7.737h3.583c.268 0 .48-.205.48-.48V2.634a.472.472 0 0 0-.48-.473.466.466 0 0 0-.473.473v4.15H3.41a.467.467 0 0 0-.48.473c0 .275.206.48.48.48ZM7 13.993c3.83 0 7-3.176 7-6.996C14 3.169 10.822 0 6.993 0 3.171 0 0 3.169 0 6.997c0 3.82 3.177 6.996 7 6.996Zm0-1.166a5.804 5.804 0 0 1-5.826-5.83c0-3.238 2.58-5.83 5.82-5.83a5.815 5.815 0 0 1 5.84 5.83A5.81 5.81 0 0 1 7 12.827Z"/> | ||||||
|                               </svg>{{this.time}}</p> |                               </svg>{{this.time}}</p> | ||||||
|                               <p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14"> |                               <p><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 5 14"> | ||||||
|                                 <path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/> |                                 <path fill="#000" fill-opacity=".75" d="M0 2.402c0 1.122.792 2.059 1.877 2.32v5.913c0 1.88.353 2.906.62 2.906.273 0 .619-1.02.619-2.906V4.722C4.2 4.467 5 3.524 5 2.402 5 1.083 3.888 0 2.497 0 1.112 0 0 1.083 0 2.402Zm1.784.134c-.46 0-.859-.382-.859-.828 0-.44.4-.816.86-.816.465 0 .851.376.851.816 0 .446-.386.828-.852.828Z"/> | ||||||
|                               </svg>{{this.latitude}},{{this.longitude}}</p> |                               </svg>{{this.latitude}},{{this.longitude}}</p> --> | ||||||
|                               <p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 24 19"> |                               <p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 24 19"> | ||||||
|                                 <path fill="#000" fill-opacity=".75" d="M4.58 6.143c-.078.341.068.478.44.459 1.562-.108 3.418-.196 6.533-.196 3.125 0 4.98.088 6.543.196.361.02.508-.118.43-.46-.235-1.035-.684-2.382-.997-2.92-.254-.439-.537-.634-1.045-.702-.703-.098-2.304-.166-4.931-.166-2.617 0-4.219.068-4.932.166-.508.068-.79.263-1.045.703-.312.537-.752 1.884-.996 2.92Zm-.068 6.65c.888 0 1.572-.684 1.572-1.572 0-.899-.684-1.573-1.572-1.573-.889 0-1.573.674-1.573 1.573 0 .888.684 1.572 1.573 1.572Zm4.463-.39h5.166c.664 0 1.123-.46 1.123-1.133 0-.665-.46-1.123-1.123-1.123H8.975c-.674 0-1.133.458-1.133 1.123 0 .673.459 1.132 1.133 1.132Zm9.619.39c.898 0 1.572-.684 1.572-1.572 0-.899-.674-1.573-1.572-1.573-.889 0-1.563.674-1.563 1.573 0 .888.674 1.572 1.563 1.572Zm-7.041 2.637c3.281 0 7.646-.166 9.492-.381 1.328-.147 2.06-.88 2.06-2.13v-1.718c0-1.65-.332-2.568-1.23-3.74l-.83-1.065c-.352-1.757-1.006-3.603-1.338-4.326C19.18.967 18.174.313 16.875.137 16.221.049 14.082 0 11.553 0 9.033 0 6.895.059 6.24.137 4.941.293 3.926.967 3.408 2.07c-.342.723-.986 2.569-1.347 4.326l-.82 1.065C.331 8.633 0 9.55 0 11.2v1.719c0 1.25.742 1.982 2.06 2.129 1.856.215 6.211.38 9.493.38Zm0-1.28c-3.32 0-7.578-.156-9.15-.351-.83-.098-1.124-.527-1.124-1.27v-1.328c0-1.338.215-1.963.977-2.959l.996-1.308c.264-1.416.898-3.39 1.318-4.288.313-.673.928-1.093 1.817-1.2.625-.079 2.607-.167 5.166-.167 2.568 0 4.58.088 5.146.166.918.117 1.524.537 1.846 1.201.42.899 1.055 2.872 1.308 4.288l1.006 1.308c.752.996.967 1.621.967 2.96v1.327c0 .742-.293 1.172-1.123 1.27-1.562.195-5.83.351-9.15.351Zm-9.756 3.965h1.142c.733 0 1.3-.566 1.3-1.289v-2.324l-3.741-.537v2.861c0 .723.566 1.29 1.299 1.29Zm18.369 0h1.152a1.27 1.27 0 0 0 1.29-1.289v-2.861l-3.731.537v2.324a1.27 1.27 0 0 0 1.289 1.29Z"/> |                                 <path fill="#000" fill-opacity=".75" d="M4.58 6.143c-.078.341.068.478.44.459 1.562-.108 3.418-.196 6.533-.196 3.125 0 4.98.088 6.543.196.361.02.508-.118.43-.46-.235-1.035-.684-2.382-.997-2.92-.254-.439-.537-.634-1.045-.702-.703-.098-2.304-.166-4.931-.166-2.617 0-4.219.068-4.932.166-.508.068-.79.263-1.045.703-.312.537-.752 1.884-.996 2.92Zm-.068 6.65c.888 0 1.572-.684 1.572-1.572 0-.899-.684-1.573-1.572-1.573-.889 0-1.573.674-1.573 1.573 0 .888.684 1.572 1.573 1.572Zm4.463-.39h5.166c.664 0 1.123-.46 1.123-1.133 0-.665-.46-1.123-1.123-1.123H8.975c-.674 0-1.133.458-1.133 1.123 0 .673.459 1.132 1.133 1.132Zm9.619.39c.898 0 1.572-.684 1.572-1.572 0-.899-.674-1.573-1.572-1.573-.889 0-1.563.674-1.563 1.573 0 .888.674 1.572 1.563 1.572Zm-7.041 2.637c3.281 0 7.646-.166 9.492-.381 1.328-.147 2.06-.88 2.06-2.13v-1.718c0-1.65-.332-2.568-1.23-3.74l-.83-1.065c-.352-1.757-1.006-3.603-1.338-4.326C19.18.967 18.174.313 16.875.137 16.221.049 14.082 0 11.553 0 9.033 0 6.895.059 6.24.137 4.941.293 3.926.967 3.408 2.07c-.342.723-.986 2.569-1.347 4.326l-.82 1.065C.331 8.633 0 9.55 0 11.2v1.719c0 1.25.742 1.982 2.06 2.129 1.856.215 6.211.38 9.493.38Zm0-1.28c-3.32 0-7.578-.156-9.15-.351-.83-.098-1.124-.527-1.124-1.27v-1.328c0-1.338.215-1.963.977-2.959l.996-1.308c.264-1.416.898-3.39 1.318-4.288.313-.673.928-1.093 1.817-1.2.625-.079 2.607-.167 5.166-.167 2.568 0 4.58.088 5.146.166.918.117 1.524.537 1.846 1.201.42.899 1.055 2.872 1.308 4.288l1.006 1.308c.752.996.967 1.621.967 2.96v1.327c0 .742-.293 1.172-1.123 1.27-1.562.195-5.83.351-9.15.351Zm-9.756 3.965h1.142c.733 0 1.3-.566 1.3-1.289v-2.324l-3.741-.537v2.861c0 .723.566 1.29 1.299 1.29Zm18.369 0h1.152a1.27 1.27 0 0 0 1.29-1.289v-2.861l-3.731.537v2.324a1.27 1.27 0 0 0 1.289 1.29Z"/> | ||||||
|                               </svg>{{this.serial}}</p> |                               </svg>{{this.serial}}</p> | ||||||
|  |                               <p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="14" fill="none" viewBox="0 0 13 14"> | ||||||
|  |                                 <path fill="rgba(255, 106, 75, 0.8)" fill-opacity=".85" d="M0 10.722c0 .494.386.82 1.04.82h2.908c.055 1.307 1.095 2.451 2.549 2.451 1.46 0 2.5-1.138 2.555-2.452h2.908c.647 0 1.04-.325 1.04-.82 0-.677-.703-1.286-1.295-1.889-.455-.467-.579-1.429-.634-2.208-.048-2.668-.75-4.389-2.583-5.04C8.253.699 7.516 0 6.497 0 5.484 0 4.74.698 4.512 1.585c-1.832.65-2.535 2.37-2.583 5.04-.055.778-.18 1.74-.634 2.207C.695 9.435 0 10.044 0 10.722Zm1.337-.203v-.082c.124-.196.537-.596.895-.989.496-.541.73-1.415.792-2.736.055-2.96.951-3.901 2.13-4.22.171-.04.268-.121.275-.298.02-.704.434-1.198 1.068-1.198.64 0 1.047.494 1.074 1.198.007.177.097.258.269.299 1.185.318 2.08 1.26 2.136 4.22.062 1.32.296 2.194.785 2.735.365.393.772.793.896.99v.08H1.337Zm3.685 1.022h2.956c-.055.922-.648 1.497-1.481 1.497-.827 0-1.427-.575-1.475-1.497Z"/> | ||||||
|  |                               </svg>{{this.type}}</p> | ||||||
|                                |                                | ||||||
|                               <!-- <p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14"> |                               <!-- <p class="name"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" viewBox="0 0 13 14"> | ||||||
|                                 <path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/> |                                 <path fill="#000" fill-opacity=".75" d="M1.82 14h9.335c1.233 0 1.82-.371 1.82-1.188 0-1.946-2.458-4.761-6.484-4.761C2.458 8.05 0 10.866 0 12.81 0 13.63.587 14 1.82 14Zm-.35-1.121c-.193 0-.274-.053-.274-.208 0-1.218 1.886-3.499 5.295-3.499 3.402 0 5.288 2.28 5.288 3.499 0 .155-.074.208-.267.208H1.47ZM6.492 7.13C8.26 7.13 9.7 5.555 9.7 3.64 9.7 1.737 8.266.244 6.49.244c-1.76 0-3.208 1.523-3.208 3.41C3.29 5.562 4.723 7.13 6.49 7.13Zm0-1.121c-1.084 0-2.012-1.04-2.012-2.355 0-1.292.913-2.287 2.012-2.287 1.107 0 2.013.98 2.013 2.272 0 1.315-.921 2.37-2.013 2.37Z"/> | ||||||
| @@ -258,14 +259,30 @@ | |||||||
|           console.log(totalCameras); |           console.log(totalCameras); | ||||||
|           playNextCamerasInGroup(); |           playNextCamerasInGroup(); | ||||||
|  |  | ||||||
|           var svgId = "marker-" + serial; |           const markers = document.querySelectorAll('.area-devices .device'); | ||||||
|           var svgElement = document.getElementById(svgId); |           markers.forEach(marker => { | ||||||
|  |             const serial = marker.querySelector('.radio-input').value; | ||||||
|  |  | ||||||
|  |             // Получаем элемент с соответствующим id | ||||||
|  |             const svgId = `marker-${serial}`; | ||||||
|  |             const svgElement = document.getElementById(svgId); | ||||||
|  |  | ||||||
|             if (svgElement) { |             if (svgElement) { | ||||||
|  |               // Проверяем serial и устанавливаем цвет | ||||||
|  |               if (serial === $("input[name=camera-serial]:checked").val()) { | ||||||
|                 svgElement.innerHTML = ` |                 svgElement.innerHTML = ` | ||||||
|                   <path fill="#FF6A4B" d="M12.669 24.673c6.565 0 12-5.435 12-12 0-6.553-5.447-12-12.012-12C6.104.673.67 6.12.67 12.673c0 6.565 5.447 12 12 12Z"/> |                   <path fill="#FF6A4B" d="M12.669 24.673c6.565 0 12-5.435 12-12 0-6.553-5.447-12-12.012-12C6.104.673.67 6.12.67 12.673c0 6.565 5.447 12 12 12Z"/> | ||||||
|               <path fill="#fff" fill-opacity=".85" d="m7.104 17.92 4.683-11.93c.33-.823 1.423-.846 1.753-.023l4.682 11.953c.318.788-.553 1.47-1.294.73l-3.953-3.953c-.188-.2-.424-.2-.612 0L8.41 18.65c-.753.74-1.623.059-1.306-.73Z"/> |                   <path fill="#fff" fill-opacity=".85" d="m7.104 17.92 4.683-11.93c.33-.823 1.423-.846 1.753-.023l4.682 11.953c.318.788-.553 1.47-1.294.73l-3.953-3.953c-.188-.2-.424-.2-.612 0L8.41 18.65c-.753.74-1.623.059-1.306-.730Z"/> | ||||||
|  |                 `; | ||||||
|  |               } else { | ||||||
|  |                 svgElement.innerHTML = ` | ||||||
|  |                   <path d="M12.9815 25.0195C19.5462 25.0336 24.9931 19.6101 25.0073 13.0454C25.0214 6.49253 19.5861 1.03375 13.0214 1.01961C6.46848 1.00549 1.02147 6.44081 1.00735 12.9937C0.993201 19.5584 6.42852 25.0054 12.9815 25.0195Z" fill="#8086F9"/> | ||||||
|  |                   <path d="M7.43175 18.2547L12.1398 6.33536C12.471 5.51254 13.5652 5.49137 13.8928 6.31561L18.5493 18.2786C18.8653 19.0675 17.9932 19.748 17.2537 19.0052L13.3092 15.0438C13.1215 14.8434 12.8862 14.8429 12.6975 15.0425L8.73605 18.9868C7.98152 19.7264 7.1124 19.0422 7.43175 18.2547Z" fill="white" fill-opacity="0.85"/> | ||||||
|                 `; |                 `; | ||||||
|               } |               } | ||||||
|  |             } | ||||||
|  |           }); | ||||||
|  |            | ||||||
|         }); |         }); | ||||||
|       }); |       }); | ||||||
|     </script> |     </script> | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| <body> | <body> | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ | |||||||
|    |    | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
| @@ -230,7 +231,7 @@ | |||||||
|  |  | ||||||
|     <style> |     <style> | ||||||
|       .table { |       .table { | ||||||
|         background-color:rgba(0, 0, 0, 0.02) !important; |         background-color:#f7f7fa !important; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       .speedometr { |       .speedometr { | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ | |||||||
|    |    | ||||||
|  |  | ||||||
|     <header> |     <header> | ||||||
|  |         <img src="../img/argus.png"> | ||||||
|         <h1>Аргус</h1> |         <h1>Аргус</h1> | ||||||
|         <h2><span>/</span> {{Organisation}}</h2> |         <h2><span>/</span> {{Organisation}}</h2> | ||||||
|     </header> |     </header> | ||||||
| @@ -208,7 +209,7 @@ | |||||||
|  |  | ||||||
|     <style> |     <style> | ||||||
|       .table { |       .table { | ||||||
|         background-color:rgba(0, 0, 0, 0.02) !important; |         background-color:#f7f7fa !important; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       .speedometr { |       .speedometr { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user