From 69ab43a4ec2e72e1b7464cefaa8f70711f8f2c18 Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Sun, 4 Jun 2023 02:00:19 +0300 Subject: [PATCH] v0.0.7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + Обновлен скрипт SQL - добавлена таблица с описанием типов USSD + Реализовано: просмотр и удаление USSD + Кнопка перезагрузки вкладки; кнопка обновления обновляет данные группы во вкладке --- database/script.sql | 15 +++ images/favicon.png | Bin 11271 -> 24788 bytes js/script.js | 190 ++++++++++++++++++++++++++++++++++---- public/style.css | 18 ++-- source/daster.d | 13 +++ source/requests/ussd.d | 39 ++++++++ source/sql.d | 115 +++++++++++++++++++++++ source/structures.d | 9 ++ views/index.dt | 9 +- views/list_ussd_groups.dt | 13 +++ views/ussd.dt | 11 +++ 11 files changed, 403 insertions(+), 29 deletions(-) create mode 100644 source/requests/ussd.d create mode 100644 views/list_ussd_groups.dt create mode 100644 views/ussd.dt diff --git a/database/script.sql b/database/script.sql index 4789ce4..1e4a1cd 100644 --- a/database/script.sql +++ b/database/script.sql @@ -44,6 +44,21 @@ create table if not exists da_sms ( constraint da_sms_pk primary key (da_id) ); +create table if not exists da_ussd_type ( + da_id bigserial not null, + da_comment varchar(100) not null, + constraint da_ussd_type_pk primary key (da_id) +); + +insert into da_ussd_type (da_id, da_comment) + values + ('0', 'Уведомление'), + ('1', 'Запрос'), + ('2', 'Прервано сетью'), + ('3', 'Ответ другого локального клиента'), + ('4', 'Операция не поддерживается'), + ('5', 'Тайм-аут сети'); + create table if not exists da_ussd ( da_id bigserial not null, da_date timestamp not null default NOW(), diff --git a/images/favicon.png b/images/favicon.png index f78f53225624e2604bf290107b54fb6d163cdd01..e22094349b706416adf6d5aab7c5ff1ffa046801 100644 GIT binary patch literal 24788 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 o_Tj*H0OkKY!Nt { loadNumbers() }, + 1: () => { loadSMS() }, + 2: () => { loadUSSD() }, + 3: () => {} + }; + + let lists = { 0: () => { showListNumbers($("#accordion-numbers .ui-accordion-content-active")) }, 1: () => { showListSMS($("#accordion-sms .ui-accordion-content-active")) }, - 2: () => {}, + 2: () => { showListUSSD($("#accordion-ussd .ui-accordion-content-active")) }, 3: () => {} }; let groups = { 0: () => { generateListGroupNumbers($("#accordion-numbers .ui-accordion-content-active")) }, 1: () => { generateListGroupSMS($("#accordion-sms .ui-accordion-content-active")) }, - 2: () => { noticer.success('Вкладка "USSD"') }, + 2: () => { generateListGroupUSSD($("#accordion-ussd .ui-accordion-content-active")) }, 3: () => { noticer.success('Вкладка "Сервер"') } }; $("button").button(); - $("#update").button("option", "icon", "ui-icon-refresh"); + $("#update-tab").button("option", "icon", "ui-icon-refresh"); + $("#update-group").button("option", "icon", "ui-icon-arrowrefresh-1-s"); $("#add-number").button("option", "icon", "ui-icon-plusthick"); $("#logout").button("option", "icon", "ui-icon-power"); $("#tabs").tabs({ activate: function( event, ui ) { - tabs[$(this).tabs( "option", "active" )](); + lists[$(this).tabs( "option", "active" )](); $("#add-number").button( "option", "disabled", $(this).tabs( "option", "active" ) > 0 ); + // $("#search").attr( "disabled", $("#search").val("") && $(this).tabs( "option", "active" ) > 1 ); } }); - $("#update").click(() => { + $("#update-tab").click(() => { + tabs[$("#tabs").tabs( "option", "active" )]() + }); + + $("#update-group").click(() => { groups[$("#tabs").tabs( "option", "active" )]() }); @@ -39,13 +53,14 @@ $(document).ready(function () { }); $("#search").on("input", function () { - tabs[$("#tabs").tabs( "option", "active" )]() + lists[$("#tabs").tabs( "option", "active" )]() }).keydown(function (e) { - e.key == "Escape" && ($(this).val(""), tabs[$("#tabs").tabs( "option", "active" )]()) + e.key == "Escape" && ($(this).val(""), lists[$("#tabs").tabs( "option", "active" )]()) }); loadNumbers(); loadSMS(); + loadUSSD(); $("body").fadeTo(500, 1); }) @@ -81,10 +96,10 @@ function isNumeric(value) { return /^-?\d+$/.test(value); } -function divNotFoundNumbers() { +function divNotFoundNumbers(text = '') { let notFound = $('.notFoundNumbers'); let divTable = $('.body-rows'); - let divNotFound = $('
'); + let divNotFound = $(`
${text}
`); divNotFound.css({ "color": "#333", @@ -92,8 +107,8 @@ function divNotFoundNumbers() { "padding": "20px 0 20px 0" }); - this.push = function(text = 'Нет номеров') { - divTable.append(divNotFound.html(text)); + this.push = function() { + divTable.append(divNotFound); } this.remove = function() { @@ -101,6 +116,10 @@ function divNotFoundNumbers() { } } +function pEmpty(text) { + return $(`

${text}

`).css('text-align', 'center'); +} + /************************************************************************************ Обработка таблицы с номерами телефонов @@ -117,7 +136,7 @@ function loadNumbers() { function generateListNumberGroups(data) { if (!$(data).children().length) { - $("#tabs-numbers").html('

Номера телефонов отсутствуют

'); + $("#tabs-numbers").html(pEmpty('Номера телефонов отсутствуют')); return; } @@ -136,7 +155,7 @@ function generateListNumberGroups(data) { function generateListGroupNumbers(panel) { if (!$("#accordion-numbers").children().length) { noticer.warning("Номера телефонов отсутствуют"); - $("#tabs-numbers").html('

Номера телефонов отсутствуют

'); + $("#tabs-numbers").html(pEmpty('Номера телефонов отсутствуют')); return; } @@ -171,7 +190,7 @@ function showListNumbers(panel, data = numbers.filter(e => e.number.includes($(" }); if (!body.children().length) - (new divNotFoundNumbers).push(); + (new divNotFoundNumbers('Нет номеров')).push(); } function viewNumber(panel, number) { @@ -321,7 +340,7 @@ function delNumber(panel, currentWindow) { /************************************************************************************ - Обработка таблицы с SMS + Обработка таблицы с SMS ************************************************************************************/ @@ -335,7 +354,7 @@ function loadSMS() { function generateListSMSGroups(data) { if (!$(data).children().length) { - $("#tabs-sms").html('

SMS отсутствуют

'); + $("#tabs-sms").html(pEmpty('SMS отсутствуют')); return; } @@ -354,7 +373,7 @@ function generateListSMSGroups(data) { function generateListGroupSMS(panel) { if (!$("#accordion-sms").children().length) { noticer.warning("SMS отсутствуют"); - $("#tabs-sms").html('

SMS отсутствуют

'); + $("#tabs-sms").html(pEmpty('SMS отсутствуют')); return; } @@ -386,7 +405,7 @@ function showListSMS(panel, data = sms.filter(e => e.from.includes($("#search"). }); if (!body.children().length) - (new divNotFoundNumbers).push(); + (new divNotFoundNumbers('Нет SMS')).push(); } function viewSMS(panel, id, number) { @@ -454,3 +473,138 @@ function delSMS(panel, currentWindow) { noticer.error(error.message); }); } + +/************************************************************************************ + + Обработка таблицы с USSD + +************************************************************************************/ + +function loadUSSD() { + request('listussdgroups', 'text').then(data => { + data.error ? noticer.error(data.message) : generateListUSSDGroups(data); + }).catch(error => { + noticer.error(error.message); + }); +} + +function generateListUSSDGroups(data) { + if (!$(data).children().length) { + $("#tabs-ussd").html(pEmpty('USSD отсутствуют')); + return; + } + + $("#tabs-ussd").html(data); + $("#accordion-ussd").accordion({ + heightStyle: "content", + create: function( event, ui ) { + generateListGroupUSSD(ui.panel); + }, + beforeActivate: function( event, ui ) { + generateListGroupUSSD(ui.newPanel); + } + }) +} + +function generateListGroupUSSD(panel) { + if (!$("#accordion-ussd").children().length) { + noticer.warning("USSD отсутствуют"); + $("#tabs-ussd").html(pEmpty('USSD отсутствуют')); + return; + } + + request('listgroupussd', 'json', { to: panel.data("to") }).then(data => { + if (isJSON(data) && JSON.parse(data).error) + noticer.error(JSON.parse(data).message); + else { + ussd = data; + showListUSSD(panel); + } + }).catch(error => { + noticer.error(error.message); + }); +} + +function showListUSSD(panel, data = ussd) { + (new divNotFoundNumbers).remove(); + let body = panel.find('.body').html(''); + $(data).each((i, j) => { + let row = $(``); + row.append(`${j.date}`); + row.append(`${j.type_comment}`); + row.append(`${j.text}`); + body.append(row); + + row.click(function() { + viewUSSD(panel, $(this).data('ussd-id'), j.type_comment); + }); + }); + + if (!body.children().length) + (new divNotFoundNumbers('Нет USSD')).push(); +} + +function viewUSSD(panel, id, type) { + request('viewussd', 'text', {id: id}).then(data => { + if (isJSON(data) && JSON.parse(data).error) + noticer.error(JSON.parse(data).message); + else { + showViewUSSD(data, [ + { + id: "btn-delete", + text: "Удалить", + icon: "ui-icon-trash", + click: function() { + delUSSD(panel, $(this)); + } + } + ], `USSD: ${type}`); + } + }).catch(error => { + noticer.error(error.message); + }); +} + +function showViewUSSD(data, actionButton, title) { + let form = $(data); + + form.appendTo('body').dialog({ + title: title, + height: 'auto', + width: 'auto', + resizable: false, + modal: true, + show: { effect: "fade", duration: 500 }, + close: function(event, ui) { + $(this).dialog('destroy').remove() + }, + buttons: [ + ...actionButton, + { + text: "Отмена", + icon: "ui-icon-cancel", + click: function() { + $(this).dialog("close"); + } + } + ] + }); +} + +function delUSSD(panel, currentWindow) { + let id = $('#ussd-content').data('id'); + + request('delussd', 'json', { + id: id + }).then(data => { + if (data.error) + noticer.error(data.message); + else { + noticer.success(`USSD было удалено`); + generateListGroupUSSD(panel); + currentWindow.dialog("close"); + } + }).catch(error => { + noticer.error(error.message); + }); +} diff --git a/public/style.css b/public/style.css index fe99a79..79134bf 100644 --- a/public/style.css +++ b/public/style.css @@ -125,7 +125,7 @@ tr.row:hover, tr.row:nth-child(even):hover { /* EDIT NUMBER */ -.number-label, .sms-label { +.number-label, .sms-label, .ussd-label { color: #333; text-align: right; } @@ -134,11 +134,11 @@ tr.row:hover, tr.row:nth-child(even):hover { height: 30px; } -.sms-label-text { +.sms-label-text, .ussd-label-text { vertical-align:top } -.sms-value { +.sms-value, .ussd-value { width: 300px; text-align: left; } @@ -171,17 +171,17 @@ tr.row:hover, tr.row:nth-child(even):hover { padding: 15px 0 5px 0; } -.comment-content, .sms-content { +.comment-content, .sms-content, .ussd-content { width: 100%; height: 100%; } -#number-comment, #sms-content { +#number-comment, #sms-content, #ussd-content { width: calc(100% - 6px); resize: none; } -#sms-content { +#sms-content, #ussd-content { height: 150px; outline: none; border: 1px solid#c5c5c5; @@ -190,6 +190,10 @@ tr.row:hover, tr.row:nth-child(even):hover { padding: 5px 10px 5px 10px; } -th.sms-content-width, td.sms-content-width { +th.sms-content-width, td.sms-content-width, th.ussd-content-width, td.ussd-content-width { width: 155px; } + +th.ussd-content-width-type, td.ussd-content-width-type { + width: 240px; +} diff --git a/source/daster.d b/source/daster.d index c4b5181..9f55970 100644 --- a/source/daster.d +++ b/source/daster.d @@ -18,6 +18,7 @@ import structures; import requests.numbers; import requests.sms; +import requests.ussd; static ServerInfo serverInfo; @@ -210,6 +211,18 @@ void postReq(HTTPServerRequest req, HTTPServerResponse res) { case "delsms": sendDelSMS(req, res); break; + case "listussdgroups": + getListUSSDGroups(req, res); + break; + case "listgroupussd": + getListGroupUSSD(req, res); + break; + case "viewussd": + getViewUSSD(req, res); + break; + case "delussd": + sendDelUSSD(req, res); + break; default: res.redirect("/"); } diff --git a/source/requests/ussd.d b/source/requests/ussd.d new file mode 100644 index 0000000..c39a46e --- /dev/null +++ b/source/requests/ussd.d @@ -0,0 +1,39 @@ +module requests.ussd; + +import vibe.vibe; +import response; +import structures; +import sql; +import singlog; + +// Получить список всех групп USSD +void getListUSSDGroups(HTTPServerRequest req, HTTPServerResponse res) { + auto numbers = sqlGetUSSDNumbers(); + render!("list_ussd_groups.dt", numbers)(res); +} + +// Получить список USSD конкретной группы +void getListGroupUSSD(HTTPServerRequest req, HTTPServerResponse res) { + auto jsr = req.json; + res.writeJsonBody(sqlGetListUSSD(jsr["to"].get!string).serializeToJson()); +} + +// Просмотр USSD +void getViewUSSD(HTTPServerRequest req, HTTPServerResponse res) { + auto jsr = req.json; + auto dataUSSD = sqlGetUSSD(jsr["id"].to!int); + render!("ussd.dt", dataUSSD)(res); +} + +// Удалить USSD +void sendDelUSSD(HTTPServerRequest req, HTTPServerResponse res) { + auto jsr = req.json; + int idussd = jsr["id"].get!int; + + if (!sqlDeleteUSSD(idussd)) { + res.send(true, "Не удалось удалить USSD"); + return; + } + + res.send(); +} diff --git a/source/sql.d b/source/sql.d index f4ccd69..5f14461 100644 --- a/source/sql.d +++ b/source/sql.d @@ -6,6 +6,12 @@ import structures; import std.conv; +/* + + Запросы для таблицы номеров телефонов + +*/ + GroupDB[] sqlGetListGroups() { GroupDB[] groups; try { @@ -201,6 +207,12 @@ bool sqlInsertNumber(NumberDB number) { return true; } +/* + + Запросы для таблицы SMS + +*/ + SMSDB[] sqlGetSMSNumbers() { SMSDB[] numbers; try { @@ -293,3 +305,106 @@ bool sqlDeleteSMS(int idsms) { } return true; } + +/* + + Запросы для таблицы USSD + +*/ + +USSDDB[] sqlGetUSSDNumbers() { + USSDDB[] numbers; + try { + auto queryResult = pgsql.sql( + "select distinct da_to from da_ussd" + ); + foreach (row; queryResult) { + USSDDB data; + + data.to = row["da_to"]; + + numbers ~= data; + } + } catch (Exception e) { + log.e("Не удалось выполнить запрос к БД. " ~ e.msg); + } + + return numbers; +} + +USSDDB[] sqlGetListUSSD(string to) { + USSDDB[] ussd; + try { + auto queryResult = pgsql.sql( + "select + dau.da_id, + to_char(dau.da_date, 'YYYY.MM.DD HH24:MI:SS') da_date, + dau.da_to, + dau.da_type, + daut.da_comment da_type_comment, + dau.da_text + from da_ussd dau + inner join da_ussd_type daut + on dau.da_type = daut.da_id + where dau.da_to = ? + order by dau.da_date desc", + to + ); + foreach (row; queryResult) { + USSDDB data; + + data.id = row["da_id"].to!int; + data.date = row["da_date"]; + data.to = row["da_to"]; + data.type = row["da_type"].to!int; + data.type_comment = row["da_type_comment"]; + data.text = row["da_text"]; + + ussd ~= data; + } + } catch (Exception e) { + log.e("Не удалось выполнить запрос к БД. " ~ e.msg); + } + + return ussd; +} + +USSDDB sqlGetUSSD(int idussd) { + USSDDB data; + try { + auto queryResult = pgsql.sql( + "select + da_id, + to_char(da_date, 'YYYY.MM.DD HH24:MI:SS') da_date, + da_to, + da_type, + da_text + from da_ussd + where da_id = ?", + idussd + ); + foreach (row; queryResult) { + data.id = row["da_id"].to!int; + data.date = row["da_date"]; + data.to = row["da_to"]; + data.type = row["da_type"].to!int; + data.text = row["da_text"]; + } + } catch (Exception e) { + log.e("Не удалось выполнить запрос к БД. " ~ e.msg); + } + + return data; +} + +bool sqlDeleteUSSD(int idussd) { + try { + pgsql.sql( + "delete from da_ussd where da_id = ?", idussd + ); + } catch (Exception e) { + log.e("Ошибка удаления USSD в БД. " ~ e.msg); + return false; + } + return true; +} diff --git a/source/structures.d b/source/structures.d index 10ccba1..ec79c5a 100644 --- a/source/structures.d +++ b/source/structures.d @@ -44,3 +44,12 @@ struct SMSDB { string from; string text; } + +struct USSDDB { + int id; + string date; + string to; + int type; + string type_comment; + string text; +} diff --git a/views/index.dt b/views/index.dt index 7c82457..c6e2f47 100644 --- a/views/index.dt +++ b/views/index.dt @@ -10,13 +10,14 @@ head script(src='script.js') body div.div-header - div.div-update.main-button - button#update div.div-add.main-button button#add-number Добавить номер - div.div-search + div.div-search.main-button input.input-focus#search(name='search', type='text', value='', placeholder='Найти номер') - // div.div-user Вы вошли как #{user.name} + div.div-update-tab.main-button + button#update-tab Перезагрузить + div.div-update-tab.main-button + button#update-group Обновить div.div-user div.div-logout button#logout Выход diff --git a/views/list_ussd_groups.dt b/views/list_ussd_groups.dt new file mode 100644 index 0000000..249fa78 --- /dev/null +++ b/views/list_ussd_groups.dt @@ -0,0 +1,13 @@ +div#accordion-ussd + - foreach (number; numbers) + h3 На номер #{number.to} + div.group-content(data-to='#{number.to}') + table + thead.head + tr + th.ussd-content-width Дата + th.ussd-content-width-type Тип + th Текст сообщения + div.body-rows + table + tbody.body diff --git a/views/ussd.dt b/views/ussd.dt new file mode 100644 index 0000000..8e80a4b --- /dev/null +++ b/views/ussd.dt @@ -0,0 +1,11 @@ +div#ussd-data + table + tbody + tr + td.ussd-label Дата: + td.ussd-value #{dataUSSD.date} + tr + td.ussd-label.ussd-label-text Текст: + td.ussd-value + div.ussd-content + textarea#ussd-content(readonly, data-id="#{dataUSSD.id}") #{dataUSSD.text}