diff --git a/package-lock.json b/package-lock.json index 8f60141..4ade9a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,13 @@ "license": "ISC", "dependencies": { "axios": "^1.5.0", + "body-parser": "^1.20.2", "dotenv": "^16.3.1", "express": "^4.18.2", "fs": "^0.0.1-security", "handlebars": "^4.7.7", "http": "^0.0.1-security", + "lodash": "^4.17.21", "mapbox-gl": "^2.15.0", "moment": "^2.29.4", "multer": "^1.4.5-lts.1", @@ -133,6 +135,29 @@ "tweetnacl": "^0.14.3" } }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -661,6 +686,11 @@ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/mapbox-gl": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-2.15.0.tgz", @@ -1065,6 +1095,20 @@ "node": ">= 0.6" } }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -1482,6 +1526,25 @@ "tweetnacl": "^0.14.3" } }, + "body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1865,6 +1928,11 @@ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==" }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "mapbox-gl": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-2.15.0.tgz", @@ -2173,6 +2241,17 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, + "raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, "readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", diff --git a/package.json b/package.json index 0f2b0b3..0c4839d 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,13 @@ "license": "ISC", "dependencies": { "axios": "^1.5.0", + "body-parser": "^1.20.2", "dotenv": "^16.3.1", "express": "^4.18.2", "fs": "^0.0.1-security", "handlebars": "^4.7.7", "http": "^0.0.1-security", + "lodash": "^4.17.21", "mapbox-gl": "^2.15.0", "moment": "^2.29.4", "multer": "^1.4.5-lts.1", diff --git a/server.js b/server.js index ffe4332..b951e04 100644 --- a/server.js +++ b/server.js @@ -10,7 +10,8 @@ const http = require("http"); const Client = require('ssh2').Client; const axios = require('axios'); const moment = require('moment'); - +const bodyParser = require('body-parser'); +const _ = require('lodash'); const storage = multer.diskStorage({ @@ -26,6 +27,7 @@ const upload = multer({ storage: storage }); app.use(express.static(path.join(__dirname, "static"))); app.use(express.json()); app.use(express.urlencoded({ extended: false })); +app.use(bodyParser.json()); app.get("/", index); app.get("/login", login); @@ -241,7 +243,7 @@ for (let i = 0; i < dates.length; i++) { } - console.log(templateData); + // console.log(templateData); const source = fs.readFileSync("static/templates/index.html", "utf8"); @@ -275,6 +277,7 @@ async function live(req, res) { Registrars: [], Alarms: [], Count: 0, + Groups: [], }; try { @@ -451,6 +454,44 @@ async function live(req, res) { templateData.Count = templateData.Alarms.length; + // Выполняем запрос, чтобы получить все данные из таблицы registrars + const queryRegistrars = ` + SELECT id, serial, channels, lastkeepalive, name, "group", plate, sim, ip, port + FROM registrars + ORDER BY id + `; + const registrarsResult = await client.query(queryRegistrars); + const allRegistrars = registrarsResult.rows; + + // Группируем устройства по группам и сохраняем данные каждого устройства + const groupedRegistrars = {}; + allRegistrars.forEach((registrar) => { + if (!groupedRegistrars[registrar.group]) { + groupedRegistrars[registrar.group] = []; + } + groupedRegistrars[registrar.group].push({ + id: registrar.id, + serial: registrar.serial, + channels: registrar.channels, + 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, + }); + }); + + // Заполняем массив групп данными устройств в каждой группе + for (const groupName in groupedRegistrars) { + templateData.Groups.push({ + name: groupName, + devices: groupedRegistrars[groupName], + }); + } + + const source = fs.readFileSync("static/templates/live.html", "utf8"); const template = handlebars.compile(source); const resultHTML = template(templateData); @@ -537,6 +578,7 @@ async function reports(req, res) { User: "Тестовое Имя", ifDBError: false, Registrars: [], + Groups: [], }; try { const pool = new Pool({ @@ -696,6 +738,32 @@ async function reports(req, res) { }; })) + // Выполняем запрос, чтобы получить все данные из таблицы registrars + const queryRegistrars = ` + SELECT id, serial, lastkeepalive, name, "group", plate, sim, ip, port + FROM registrars + ORDER BY id + `; + const registrarsResult = await client.query(queryRegistrars); + const allRegistrars = registrarsResult.rows; + + // Группируем устройства по группам + const groupedRegistrars = {}; + allRegistrars.forEach((registrar) => { + if (!groupedRegistrars[registrar.group]) { + groupedRegistrars[registrar.group] = []; + } + groupedRegistrars[registrar.group].push(registrar.serial); + }); + + // Заполняем массив групп и серийными номерами устройств в каждой группе + for (const groupName in groupedRegistrars) { + templateData.Groups.push({ + name: groupName, + serials: groupedRegistrars[groupName], + }); + } + const source = fs.readFileSync( "static/templates/reports/index.html", "utf8" @@ -1069,6 +1137,7 @@ async function devices(req, res) { User: "Тестовое Имя", ifDBError: false, Registrars: [], + Groups: [], }; try { @@ -1103,9 +1172,26 @@ async function devices(req, res) { sim: registrar.sim, ip: registrar.ip, port: registrar.port, - })), + })); + + // Группируем устройства по группам + const groupedRegistrars = {}; + allRegistrars.forEach((registrar) => { + if (!groupedRegistrars[registrar.group]) { + groupedRegistrars[registrar.group] = []; + } + groupedRegistrars[registrar.group].push(registrar.serial); + }); + + // Заполняем массив групп и серийными номерами устройств в каждой группе + for (const groupName in groupedRegistrars) { + templateData.Groups.push({ + name: groupName, + serials: groupedRegistrars[groupName], + }); + } - console.log(templateData); + // console.log(templateData); const source = fs.readFileSync("static/templates/devices/index.html", "utf8"); const template = handlebars.compile(source); @@ -1127,6 +1213,133 @@ async function devices(req, res) { } } +async function getParameterByName(serial, fieldName) { + const requestPayload = { + FIELDS: [fieldName], + }; + + const requestResponse = await axios.get(`http://krbl.ru:8080/http/parameters/request?serial=${serial}`, { + headers: { + 'Content-Type': 'application/json', + }, + data: JSON.stringify(requestPayload), + }); + // console.log(requestResponse.data); + + const getResponse = await axios.get(`http://krbl.ru:8080/http/parameters/get?serial=${serial}`); + // console.log(getResponse.data); + + const fieldPath = findPathForField(fieldName); + if (fieldPath) { + const value = _.get(getResponse.data, fieldPath); + return { [fieldName]: value }; + } + return null; +} + +app.post('/device-parameters', async (req, res) => { + try { + const { serial, FIELDS } = req.body; + // console.log(serial, FIELDS); + + const responseData = {}; + + // Используем асинхронный цикл для выполнения GET-запросов по очереди + for (const field of FIELDS) { + const parameter = await getParameterByName(serial, field); + if (parameter) { + Object.assign(responseData, parameter); + } + } + + // console.log(responseData); + + res.json(responseData); + } catch (error) { + console.error(error); + res.status(500).json({ error: 'Internal server error' }); + } +}); + +function findPathForField(fieldName) { + const fieldPathMap = { + "VEHICLEID": "DATA.RIP.BN", + "DATEMOD": "DATA.TIMEP.DATEM", + "TIMEFORMAT": "DATA.TIMEP.TIMEM", + "LANGUAGE": "DATA.GSP.LANT", + "VIDEOFORMAT": "DATA.GSP.VGA", + "GEOMOD": "DATA.GSP.GM", + "SUBSTREAMMODE": "DATA.SUBSTRNET.SM", + "NETWORK": "DATA.SUBSTRNET.NEC", + "DISPLAYMENU": "DATA.DOSD", + "RECORDINGPARAMS": "DATA.RP.RCP", + "FUTURERECORDINGSTYLE": "DATA.MP.OT", + "FUTURERECORDING": "DATA.MP.OT", + "STREAMPARAMS": "DATA.AR.VEC", + "VIDEOIMAGEMOD": "DATA.SVIP", + }; + + return fieldPathMap[fieldName] || null; +} + +app.put('/device-parameters', async (req, res) => { + // Получаем данные из PUT запроса + const requestData = req.body; + const { serial } = req.query; + + // Извлекаем необходимые параметры + const { + DATEMOD, + TIMEFORMAT, + LANGUAGE, + VIDEOFORMAT, + GEOMOD, + SUBSTREAMMODE, + NE, + TE, + VE, + SE, + GE + } = requestData; + + // Создаем JSON для GET запроса + const requestBody = { + TIMEP: { + DATEM: parseInt(DATEMOD, 10) || 1, + TIMEM: parseInt(TIMEFORMAT, 10) || 0 + }, + GSP: { + LANT: parseInt(LANGUAGE, 10) || 12, + VGA: parseInt(VIDEOFORMAT, 10) || 0, + GM: parseInt(GEOMOD, 10) || 0 + }, + SUBSTRNET: { + SM: parseInt(SUBSTREAMMODE, 10) || 1 + }, + DOSD: { + NE: parseInt(NE, 10) || 1, + TE: parseInt(TE, 10) || 1, + VE: parseInt(VE, 10) || 0, + SE: parseInt(SE, 10) || 0, + GE: parseInt(GE, 10) || 0 + } + }; + + // Отправляем GET запрос с JSON BODY + try { + const response = await axios.get(`http://krbl.ru:8080/http/parameters/set?serial=${serial}`, { + data: JSON.stringify(requestBody), + headers: { + 'Content-Type': 'application/json' + } + }); + res.status(response.status).send(response.data); + } catch (error) { + res.status(500).send('Произошла ошибка при отправке GET запроса.'); + } +}); + + app.post("/devicedata", async (req, res) => { const id = req.body.id; @@ -1556,6 +1769,7 @@ async function videos(req, res) { User: "Тестовое Имя", ifDBError: false, Registrars: [], + Groups: [], }; try { @@ -1581,6 +1795,43 @@ async function videos(req, res) { status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis, })); + // Выполняем запрос, чтобы получить все данные из таблицы registrars + const queryRegistrars = ` + SELECT id, serial, channels, lastkeepalive, name, "group", plate, sim, ip, port + FROM registrars + ORDER BY id + `; + const registrarsResult = await client.query(queryRegistrars); + const allRegistrars = registrarsResult.rows; + + // Группируем устройства по группам и сохраняем данные каждого устройства + const groupedRegistrars = {}; + allRegistrars.forEach((registrar) => { + if (!groupedRegistrars[registrar.group]) { + groupedRegistrars[registrar.group] = []; + } + groupedRegistrars[registrar.group].push({ + id: registrar.id, + serial: registrar.serial, + channels: registrar.channels, + 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, + }); + }); + + // Заполняем массив групп данными устройств в каждой группе + for (const groupName in groupedRegistrars) { + templateData.Groups.push({ + name: groupName, + devices: groupedRegistrars[groupName], + }); + } + // console.log(templateData); const source = fs.readFileSync("static/templates/videos/playback.html", "utf8"); @@ -1606,6 +1857,7 @@ async function videoExport(req, res) { User: "Тестовое Имя", ifDBError: false, Registrars: [], + Groups: [], }; try { @@ -1631,6 +1883,44 @@ async function videoExport(req, res) { status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis, })); + // Выполняем запрос, чтобы получить все данные из таблицы registrars + const queryRegistrars = ` + SELECT id, serial, channels, lastkeepalive, name, "group", plate, sim, ip, port + FROM registrars + ORDER BY id + `; + const registrarsResult = await client.query(queryRegistrars); + const allRegistrars = registrarsResult.rows; + + // Группируем устройства по группам и сохраняем данные каждого устройства + const groupedRegistrars = {}; + allRegistrars.forEach((registrar) => { + if (!groupedRegistrars[registrar.group]) { + groupedRegistrars[registrar.group] = []; + } + groupedRegistrars[registrar.group].push({ + id: registrar.id, + serial: registrar.serial, + channels: registrar.channels, + 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, + }); + }); + + // Заполняем массив групп данными устройств в каждой группе + for (const groupName in groupedRegistrars) { + templateData.Groups.push({ + name: groupName, + devices: groupedRegistrars[groupName], + }); + } + + // console.log(templateData); const source = fs.readFileSync("static/templates/videos/export.html", "utf8"); diff --git a/static/scripts/device-form.js b/static/scripts/device-form.js index e9d837e..624115a 100644 --- a/static/scripts/device-form.js +++ b/static/scripts/device-form.js @@ -13,6 +13,7 @@ const content1 = document.getElementById("details"); const content2 = document.getElementById("sim"); const content3 = document.getElementById("ts"); const content4 = document.getElementById("equipment"); +const content5 = document.getElementById("parameters"); const btn1 = document.getElementById("continue-details"); const btn2 = document.getElementById("continue-sim"); const btn3 = document.getElementById("continue-ts"); @@ -103,6 +104,8 @@ for (let radioButton of radioButtons) { switchContent(content3); } else if (radioButton.value === "equipment") { switchContent(content4); + } else if (radioButton.value === "parameters") { + switchContent(content5); } }); } diff --git a/static/scripts/table-drivers.js b/static/scripts/table-drivers.js index 2aa5e9c..79aa4b4 100644 --- a/static/scripts/table-drivers.js +++ b/static/scripts/table-drivers.js @@ -1,115 +1,4 @@ -// const devices = [ -// { -// id: "2", -// group: "2-device-2", -// driverID: "233", -// name: "Иван", -// surname: "Спахов", -// numberTS: "008803559E", -// phone: "+7 999 123 45 67", -// mail: "spahov@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "6", -// group: "2-device-1", -// driverID: "782", -// name: "Александр", -// surname: "Богаченко", -// numberTS: "0088036B78", -// phone: "+7 989 443 23 46", -// mail: "bogachenko@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "7", -// group: "2-device-4", -// driverID: "2943", -// name: "Михаил", -// surname: "Гукасян", -// numberTS: "009800852A", -// phone: "+7 909 133 55 67", -// mail: "agucasyan@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "8", -// group: "2-device-4", -// driverID: "87", -// name: "Марат", -// surname: "Шмидт", -// numberTS: "009800858D", -// phone: "+7 915 555 45 89", -// mail: "shmidt@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "9", -// group: "1-device-1", -// driverID: "823", -// name: "Никита", -// surname: "Ильяшенко", -// numberTS: "00980084FD", -// phone: "+7 909 123 45 67", -// mail: "iluashenko@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "10", -// group: "2-device-4", -// driverID: "15", -// name: "Валерий", -// surname: "Сараев", -// numberTS: "0088036B7F", -// phone: "+7 909 123 45 67", -// mail: "saraev@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "11", -// group: "2-device-3", -// driverID: "423", -// name: "Александр", -// surname: "Курочкин", -// numberTS: "00880302CD", -// phone: "+7 999 123 45 67", -// mail: "curochkin@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "12", -// group: "1-device-2", -// driverID: "6456", -// name: "Екатерина", -// surname: "Миненко", -// numberTS: "008802A035", -// phone: "+7 999 123 45 67", -// mail: "minenko@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "13", -// group: "3-device-1", -// driverID: "887", -// name: "Виталий", -// surname: "Гаспарян", -// numberTS: "008802A96A", -// phone: "+7 999 123 45 67", -// mail: "gosparyan@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// { -// id: "15", -// group: "1-device-1", -// driverID: "742", -// name: "Светлана", -// surname: "Амусова", -// numberTS: "00880302C7", -// phone: "+7 999 123 45 67", -// mail: "amusova@mail.ru", -// driverCard: "RUD0000000000111", -// }, -// ]; + // Получаем высоту таблицы и определяем, сколько строк помещается на странице let currentPage = 1; diff --git a/static/scripts/table-reports.js b/static/scripts/table-reports.js index d24dd1d..80f2f89 100644 --- a/static/scripts/table-reports.js +++ b/static/scripts/table-reports.js @@ -1,105 +1,3 @@ -// const devices = [ -// { -// id: "1", -// group: "0001", -// name: "Разговор по телефону", -// reportID: "354", -// plate: "AO30877", -// numberTS: "008803559E", -// time: "12.03.23 17:33", -// place: "59.852371, 30.344543", -// }, -// { -// id: "2", -// group: "0001", -// name: "Водитель зевает", -// reportID: "353", -// plate: "AO64377", -// numberTS: "0088036B78", -// time: "12.03.23 14:26", -// place: "60.058236, 30.315283", -// }, -// { -// id: "3", -// group: "0002", -// name: "Усталость", -// reportID: "352", -// plate: "ГД44377", -// numberTS: "009800852A", -// time: "12.03.23 10:07", -// place: "59.878256, 30.31962", -// }, -// { -// id: "4", -// group: "0003", -// name: "Водитель зевает", -// reportID: "351", -// plate: "УА86577", -// numberTS: "009800858D", -// time: "12.03.23 09:56", -// place: "60.045981, 30.4134", -// }, -// { -// id: "5", -// group: "0003", -// name: "Разговор по телефону", -// reportID: "350", -// plate: "БВ74665", -// numberTS: "00980084FD", -// time: "11.03.23 20:43", -// place: "59.83257, 30.389893", -// }, -// { -// id: "6", -// group: "0004", -// name: "Разговор по телефону", -// reportID: "349", -// plate: "ЦУ445101", -// numberTS: "0088036B7F", -// time: "11.03.23 19:17", -// place: "59.959926, 30.42224", -// }, -// { -// id: "7", -// group: "0005", -// name: "Усталость", -// reportID: "348", -// plate: "КТ32376", -// numberTS: "00880302CD", -// time: "11.03.23 15:32", -// place: "60.046346, 30.405688", -// }, -// { -// id: "8", -// group: "0006", -// name: "Курение за рулём", -// reportID: "347", -// plate: "ОА33277", -// numberTS: "008802A035", -// time: "11.03.23 15:06", -// place: "59.956626, 30.234408", -// }, -// { -// id: "9", -// group: "0007", -// name: "Водитель отвлекся", -// reportID: "346", -// plate: "КЛ987102", -// numberTS: "008802A96A", -// time: "11.03.23 12:44", -// place: "59.956626, 30.234408", -// }, -// { -// id: "10", -// group: "0002", -// name: "Водитель отвлекся", -// reportID: "345", -// plate: "АУ22377", -// numberTS: "00880302C7", -// time: "11.03.23 11:40", -// place: "59.956626, 30.234408", -// }, -// ]; // Получаем высоту таблицы и определяем, сколько строк помещается на странице let currentPage = 1; @@ -245,7 +143,7 @@ const applyFilterAndSearch = () => { const searchString = `${device.group} ${device.name} ${device.id} ${device.place} ${device.numberTS} ${device.time} ${device.place} ${device.geo} ${device.serial}`.toLowerCase(); const matchGroup = - groupFilters.length === 0 || groupFilters.includes(device.group); + groupFilters.length === 0 || groupFilters.includes(device.group) || groupFilters.includes(device.serial); const matchSearch = !searchValue || searchString.includes(searchValue); // Фильтр по временному диапазону diff --git a/static/scripts/table.js b/static/scripts/table.js index db5a826..3fb209e 100644 --- a/static/scripts/table.js +++ b/static/scripts/table.js @@ -1,172 +1,3 @@ -// const devices = [ -// { -// id: "1", -// group: "2-device-1", -// name: "Трамваи", -// plate: "AB1234", -// serial: "008803559E", -// sim: "1234567890", -// channels: 12, -// ip: "192.168.0.1", -// port: 17891, -// }, -// { -// id: "2", -// group: "2-device-2", -// name: "Электробусы", -// plate: "BC2345", -// serial: "008803559E", -// sim: "2345678901", -// channels: 12, -// ip: "192.168.0.2", -// port: 17891, -// }, -// { -// id: "3", -// group: "2-device-1", -// name: "Трамваи", -// plate: "CD3456", -// serial: "009800852A", -// sim: "3456789012", -// channels: 16, -// ip: "192.168.0.3", -// port: 17891, -// }, -// { -// id: "4", -// group: "2-device-3", -// name: "Троллейбусы", -// plate: "DE4567", -// serial: "009800858D", -// sim: "4567890123", -// channels: 12, -// ip: "192.168.0.4", -// port: 17891, -// }, -// { -// id: "5", -// group: "2-device-2", -// name: "Электробусы", -// plate: "EF5678", -// serial: "00980084FD", -// sim: "5678901234", -// channels: 16, -// ip: "192.168.0.5", -// port: 17891, -// }, -// { -// id: "6", -// group: "2-device-1", -// name: "Трамваи", -// plate: "FG6789", -// serial: "0088036B7F", -// sim: "6789012345", -// channels: 16, -// ip: "192.168.0.6", -// port: 17891, -// }, -// { -// id: "7", -// group: "2-device-4", -// name: "Старые ТС", -// plate: "GH7890", -// serial: "00880302CD", -// sim: "7890123456", -// channels: 12, -// ip: "192.168.0.7", -// port: 17891, -// }, -// { -// id: "8", -// group: "2-device-4", -// name: "Старые ТС", -// plate: "HI8901", -// serial: "008802A035", -// sim: "8901234567", -// channels: 12, -// ip: "192.168.0.8", -// port: 17891, -// }, -// { -// id: "9", -// group: "1-device-1", -// name: "Трамваи", -// plate: "IJ9012", -// serial: "008802A96A", -// sim: "9012345678", -// channels: 16, -// ip: "192.168.0.9", -// port: 17891, -// }, -// { -// id: "10", -// group: "2-device-4", -// name: "Старые ТС", -// plate: "КТ32376", -// serial: "00880302C7", -// sim: "7012345678", -// channels: 14, -// ip: "192.168.0.10", -// port: 17891, -// }, -// { -// id: "11", -// group: "2-device-3", -// name: "Троллейбусы", -// plate: "ОА33277", -// serial: "008802A035", -// sim: "9034234348", -// channels: 12, -// ip: "192.168.0.11", -// port: 17891, -// }, -// { -// id: "12", -// group: "1-device-2", -// name: "Маршрутки", -// plate: "КЛ987102", -// serial: "009800852A", -// sim: "9023345678", -// channels: 10, -// ip: "192.168.0.12", -// port: 17891, -// }, -// { -// id: "13", -// group: "3-device-1", -// name: "Троллейбусы", -// plate: "КЛ987102", -// serial: "0088036B78", -// sim: "9023345678", -// channels: 8, -// ip: "192.168.0.13", -// port: 17891, -// }, -// { -// id: "14", -// group: "3-device-1", -// name: "Маршрутки", -// plate: "КЛ987102", -// serial: "0088036B7F", -// sim: "9023345678", -// channels: 8, -// ip: "192.168.0.14", -// port: 17891, -// }, -// { -// id: "15", -// group: "1-device-1", -// name: "Трамваи", -// plate: "КЛ987102", -// serial: "008802A96A", -// sim: "9023345678", -// channels: 16, -// ip: "192.168.0.15", -// port: 17891, -// }, -// ]; - -console.log(devices); // Получаем высоту таблицы и определяем, сколько строк помещается на странице let currentPage = 1; @@ -208,7 +39,7 @@ const createTable = () => { // Добавляем ячейки с данными const name = document.createElement("td"); - name.textContent = device.name; + name.textContent = device.group; row.appendChild(name); const plate = document.createElement("td"); plate.textContent = device.plate; @@ -326,7 +157,7 @@ const applyFilterAndSearch = () => { const searchString = `${device.group} ${device.name} ${device.plate} ${device.number} ${device.serial} ${device.sim} ${device.channels} ${device.ip} ${device.port}`.toLowerCase(); const matchGroup = - groupFilters.length === 0 || groupFilters.includes(device.group); + groupFilters.length === 0 || groupFilters.includes(device.group) || groupFilters.includes(device.serial); const matchSearch = !searchValue || searchString.includes(searchValue); return matchGroup && matchSearch; }); diff --git a/static/styles/main.css b/static/styles/main.css index 445b8f8..7fd3e83 100644 --- a/static/styles/main.css +++ b/static/styles/main.css @@ -430,20 +430,24 @@ header h2 span { width: fit-content; } -.organisation label { +.organisation label, +#parameters label { color: rgba(0, 0, 0, 0.5); - cursor: pointer; + cursor: pointer !important; } -.organisation .checkbox-label:hover { - color: rgba(0, 0, 0, 0.7); +.organisation .checkbox-label:hover, +.add-new .checkbox-label:hover { + color: rgba(0, 0, 0, 0.7) !important; } -.organisation .checkbox-input:checked + .checkbox-label { - color: rgba(0, 0, 0, 0.9); +.organisation .checkbox-input:checked + .checkbox-label, +.add-new .checkbox-input:checked + .checkbox-label { + color: rgba(0, 0, 0, 0.9) !important; } -.organisation .checkmark { +.organisation .checkmark, +.add-new .checkmark { display: inline-block; width: 18px; height: 18px; @@ -453,11 +457,13 @@ header h2 span { transition: 0.2s; } -.organisation .checkbox-input:hover + .checkbox-label .checkmark { - filter: brightness(0.95); +.organisation .checkbox-input:hover + .checkbox-label .checkmark, +.add-new .checkbox-input:hover + .checkbox-label .checkmar { + filter: brightness(0.95) !important; } -.organisation .checkbox-input:checked + .checkbox-label .checkmark { +.organisation .checkbox-input:checked + .checkbox-label .checkmark, +.add-new .checkbox-input:checked + .checkbox-label .checkmark { background: url(../img/checkbox-check.svg); } @@ -648,10 +654,15 @@ td { color: rgba(0, 0, 0, 0.75); } -.table input[type="checkbox"] { +.table input[type="checkbox"], +#parameters input[type="checkbox"] { display: none; } +#parameters .checkbox-label { + margin-top: 10px; +} + .table .checkmark { margin-left: 15px; width: 22px; diff --git a/static/templates/devices/index.html b/static/templates/devices/index.html index 5565583..cdd6d7c 100644 --- a/static/templates/devices/index.html +++ b/static/templates/devices/index.html @@ -79,25 +79,15 @@