diff --git a/db/UDO_PKG_EQUIPDS_BASE.pck b/db/UDO_PKG_EQUIPDS_BASE.pck index d099b0f..5d40642 100644 --- a/db/UDO_PKG_EQUIPDS_BASE.pck +++ b/db/UDO_PKG_EQUIPDS_BASE.pck @@ -325,13 +325,6 @@ create or replace package UDO_PKG_EQUIPDS_BASE as BFORECAST in blob -- Данные прогноза ); - /* Базовая установка идентификатора очереди обмена "Выборки данных оборудования (классы оборудования, файлы данных, история запросов)" */ - procedure CMMLH_SET_EXSQUEUE - ( - NRN in number, -- Регистрационный номер - NEXSQUEUE in number -- Идентификатор очереди обмена - ); - end UDO_PKG_EQUIPDS_BASE; / create or replace package body UDO_PKG_EQUIPDS_BASE as @@ -1292,9 +1285,9 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as NRN := GEN_ID(); /* Добавляем запись */ insert into UDO_T_EQUIPDSCMMLH - (RN, PRN, EQCONFIG, RQ_AUTHID, RQ_DATE, RQ, FORECAST, EXSQUEUE) + (RN, PRN, EQCONFIG, RQ_AUTHID, RQ_DATE, RQ, FORECAST) values - (NRN, NPRN, NEQCONFIG, SRQ_AUTHID, DRQ_DATE, BRQ, null, null); + (NRN, NPRN, NEQCONFIG, SRQ_AUTHID, DRQ_DATE, BRQ, null); end CMMLH_INS; /* Базовое удаление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ @@ -1320,17 +1313,5 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as update UDO_T_EQUIPDSCMMLH T set T.FORECAST = BFORECAST where T.RN = NRN; end CMMLH_SET_FORECAST; - /* Базовая установка идентификатора очереди обмена "Выборки данных оборудования (классы оборудования, файлы данных, история запросов)" */ - procedure CMMLH_SET_EXSQUEUE - ( - NRN in number, -- Регистрационный номер - NEXSQUEUE in number -- Идентификатор очереди обмена - ) - is - begin - /* Установим идентификатор очереди обмена */ - update UDO_T_EQUIPDSCMMLH T set T.EXSQUEUE = NEXSQUEUE where T.RN = NRN; - end CMMLH_SET_EXSQUEUE; - end UDO_PKG_EQUIPDS_BASE; / diff --git a/db/UDO_PKG_EQUIPTCF.pck b/db/UDO_PKG_EQUIPTCF.pck index 02759d6..9ff10fe 100644 --- a/db/UDO_PKG_EQUIPTCF.pck +++ b/db/UDO_PKG_EQUIPTCF.pck @@ -61,14 +61,12 @@ create or replace package UDO_PKG_EQUIPTCF as COUT out clob -- Сериализованная карточка ); - /* Подчистка после исполнения запроса на формирование прогноза технического объекта */ - procedure EQCONFIG_THOBJ_FORECAST_EPLG + /* Подчистка буферов после исполнения запроса на формирование прогноза технического объекта */ + procedure EQCONFIG_THOBJ_FORECAST_BCLR ( - NDATASET_IDENT in number, -- Идентификатор буфера данных - NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных - NEQCONFIG in number := null, -- Рег. номер технического объекта - NEQUIPDSCMML in number := null, -- Рег. номер модели - CFORECAST in clob := null -- Данные прогноза + NDATASET_IDENT in number, -- Идентификатор буфера данных + NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных + NREQUEST_CONFIG_IDENT in number -- Идентификатор буфера описания запроса ); /* Подготовка запроса на формирование прогноза технического объекта */ @@ -77,6 +75,7 @@ create or replace package UDO_PKG_EQUIPTCF as NEQUIPDSCMML in number, -- Рег. номер модели NDATASET_IDENT in number, -- Идентификатор буфера данных NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных + NREQUEST_CONFIG_IDENT in number, -- Идентификатор буфера описания запроса SURL out varchar2, -- Адрес для запроса SAUTH_TOKEN out varchar2, -- Токен аутентификации для запроса SDATASET_ID out varchar2, -- Идентификатор выборки данных запроса @@ -86,6 +85,17 @@ create or replace package UDO_PKG_EQUIPTCF as STASK out varchar2 -- Задача для запроса (см. константы UDO_PKG_EQUIPDS_BASE.SCMML_TASK_*) ); + /* Финализация исполнения запроса на формирование прогноза технического объекта */ + procedure EQCONFIG_THOBJ_FORECAST_EPLG + ( + NDATASET_IDENT in number, -- Идентификатор буфера данных + NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных + NREQUEST_CONFIG_IDENT in number, -- Идентификатор буфера описания запроса + NEQCONFIG in number := null, -- Рег. номер технического объекта + NEQUIPDSCMML in number := null, -- Рег. номер модели + CFORECAST in clob := null -- Данные прогноза + ); + /* Формирование цвета прогноза для технического объекта */ function EQCONFIG_THOBJ_FORECAST_CLR ( @@ -726,40 +736,27 @@ text="Проверка прав доступа при формировании PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR); end EQCONFIG_THOBJ_CARD; - /* Подчистка после исполнения запроса на формирование прогноза технического объекта */ - procedure EQCONFIG_THOBJ_FORECAST_EPLG + /* Подчистка буферов после исполнения запроса на формирование прогноза технического объекта */ + procedure EQCONFIG_THOBJ_FORECAST_BCLR ( - NDATASET_IDENT in number, -- Идентификатор буфера данных - NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных - NEQCONFIG in number := null, -- Рег. номер технического объекта - NEQUIPDSCMML in number := null, -- Рег. номер модели - CFORECAST in clob := null -- Данные прогноза + NDATASET_IDENT in number, -- Идентификатор буфера данных + NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных + NREQUEST_CONFIG_IDENT in number -- Идентификатор буфера описания запроса ) is - NEQUIPDSCMMLH PKG_STD.TREF; -- Рег. номер истории запросов модели begin /* Очистим данные в файловом буфере */ P_FILE_BUFFER_CLEAR(NIDENT => NDATASET_IDENT); P_FILE_BUFFER_CLEAR(NIDENT => NDATASET_CONFIG_IDENT); - /* Если указаны данные технического объекта */ - if ((NEQCONFIG is not null) and (NEQUIPDSCMML is not null)) then - /* Добавляем запись истории запросов */ - UDO_PKG_EQUIPDS_BASE.CMMLH_INS(NPRN => NEQUIPDSCMML, - NEQCONFIG => NEQCONFIG, - SRQ_AUTHID => UTILIZER(), - DRQ_DATE => sysdate, - BRQ => null, - NRN => NEQUIPDSCMMLH); - /* Сохраним данные прогноза */ - UDO_PKG_EQUIPDS_BASE.CMMLH_SET_FORECAST(NRN => NEQUIPDSCMMLH, BFORECAST => BASE64_DECODE(LCSRCE => CFORECAST)); - end if; - end EQCONFIG_THOBJ_FORECAST_EPLG; - - /* Подчистка после исполнения запроса на формирование прогноза технического объекта (в автономной транзакции) */ - procedure EQCONFIG_THOBJ_FORECAST_EPLGAT + P_FILE_BUFFER_CLEAR(NIDENT => NREQUEST_CONFIG_IDENT); + end EQCONFIG_THOBJ_FORECAST_BCLR; + + /* Подчистка буферов после исполнения запроса на формирование прогноза технического объекта (в автономной транзакции) */ + procedure EQCONFIG_THOBJ_FORECAST_BCLRAT ( NDATASET_IDENT in number, -- Идентификатор буфера данных - NDATASET_CONFIG_IDENT in number -- Идентификатор буфера описания данных + NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных + NREQUEST_CONFIG_IDENT in number -- Идентификатор буфера описания запроса ) is RPROC_PARAMS PKG_CONTPRMLOC.TCONTAINER; -- Параметры процедуры @@ -775,20 +772,25 @@ text="Проверка прав доступа при формировании SNAME => 'NDATASET_CONFIG_IDENT', NVALUE => NDATASET_CONFIG_IDENT, NIN_OUT => PKG_STD.PARAM_TYPE_IN()); + PKG_CONTPRMLOC.PUTN(RCONTAINER => RPROC_PARAMS, + SNAME => 'NREQUEST_CONFIG_IDENT', + NVALUE => NREQUEST_CONFIG_IDENT, + NIN_OUT => PKG_STD.PARAM_TYPE_IN()); /* Подчищаем (в автономной транзакции) */ - PKG_SQL_CALL.EXECUTE_STORED_AT(SSTORED_NAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_EPLG', + PKG_SQL_CALL.EXECUTE_STORED_AT(SSTORED_NAME => 'UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_BCLR', RPARAM_CONTAINER => RPROC_PARAMS, BOVERLOAD_ENV => true); /* Очищаем контейнер с параметрами */ PKG_CONTPRMLOC.PURGE(RCONTAINER => RPROC_PARAMS); - end EQCONFIG_THOBJ_FORECAST_EPLGAT; - + end EQCONFIG_THOBJ_FORECAST_BCLRAT; + /* Подготовка запроса на формирование прогноза технического объекта */ procedure EQCONFIG_THOBJ_FORECAST_PRLG ( NEQUIPDSCMML in number, -- Рег. номер модели NDATASET_IDENT in number, -- Идентификатор буфера данных NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных + NREQUEST_CONFIG_IDENT in number, -- Идентификатор буфера описания запроса SURL out varchar2, -- Адрес для запроса SAUTH_TOKEN out varchar2, -- Токен аутентификации для запроса SDATASET_ID out varchar2, -- Идентификатор выборки данных запроса @@ -822,28 +824,45 @@ text="Проверка прав доступа при формировании and T.BDATA is not null; exception when others then - P_EXCEPTION(0, 'Не удалось проверить выборку данных для прогноза.'); + P_EXCEPTION(0, 'Не удалось проверить набор данных о наработках.'); end; if (NCNT > 1) then - P_EXCEPTION(0, - 'Процедура формирования данных для прогноза вернула более одного набора сведений о наработках.'); + P_EXCEPTION(0, 'Набор данных о наработках определён неоднозначно.'); end if; if (NCNT = 0) then - P_EXCEPTION(0, - 'Процедура формирования данных для прогноза не вернула сведений о наработках.'); + P_EXCEPTION(0, 'Набор данных о наработках не определён.'); end if; /* Читаем описание данных о наработках */ for C in (select T.DATA CDATA from FILE_BUFFER T where T.IDENT = NDATASET_CONFIG_IDENT) loop if (CDATASET_CONFIG is not null) then P_EXCEPTION(0, - 'Процедура формирования данных для прогноза вернула более одного описания сведений о наработках.'); + 'Описание набора данных о наработках определёно неоднозначно.'); end if; CDATASET_CONFIG := C.CDATA; end loop; if (CDATASET_CONFIG is null) then + P_EXCEPTION(0, 'Описание набора данных о наработках не определёно.'); + end if; + /* Проверим данные конфигурации запроса */ + begin + select count(T.RN) + into NCNT + from FILE_BUFFER T + where T.IDENT = NREQUEST_CONFIG_IDENT + and T.BDATA is not null; + exception + when others then + P_EXCEPTION(0, + 'Не удалось проверить параметры запроса на прогнозирование.'); + end; + if (NCNT > 1) then P_EXCEPTION(0, - 'Процедура формирования данных для прогноза не вернула описания сведений о наработках.'); + 'Параметры запроса на прогнозирование определёны неоднозначно.'); + end if; + if (NCNT = 0) then + P_EXCEPTION(0, + 'Параметры запроса на прогнозирование не определёны.'); end if; /* Читаем запись модели */ REQUIPDSCMML := UDO_PKG_EQUIPDS_BASE.CMML_GET(NFLAG_SMART => 0, NRN => NEQUIPDSCMML); @@ -870,7 +889,7 @@ text="Проверка прав доступа при формировании SAUTH_TOKEN := TO_CHAR(BASE64_ENCODE(CLOB2BLOB(REXSSERVICE_SEND_RQ.SRV_USER || ':' || BLOB2CLOB(BASE64_DECODE(REXSSERVICE_SEND_RQ.SRV_PASS))))); /* Формируем идентификатор выборки данных для запроса (в данном случае - просто уникальный идентификатор выборки, ссылка на которую будет передана в "data_url" с запросом на прогноз) */ - SDATASET_ID := TO_CHAR(NDATASET_IDENT); + SDATASET_ID := TO_CHAR(NDATASET_IDENT); /* Читаем функию и сервис обмена, применяемые для публикации данных наработки модели */ REXSSERVICEFN_FRCST_MD := GET_EXSSERVICEFN_ID(NFLAG_SMART => 0, NRN => REQUIPDSCM.EXSSERVICEFN_FRCST_MD); REXSSERVICE_FRCST_MD := GET_EXSSERVICE_ID(NFLAG_SMART => 0, NRN => REXSSERVICEFN_FRCST_MD.PRN); @@ -895,10 +914,62 @@ text="Проверка прав доступа при формировании exception when others then /* Подчистим буферы */ - EQCONFIG_THOBJ_FORECAST_EPLGAT(NDATASET_IDENT => NDATASET_IDENT, NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT); + EQCONFIG_THOBJ_FORECAST_BCLRAT(NDATASET_IDENT => NDATASET_IDENT, + NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT, + NREQUEST_CONFIG_IDENT => NREQUEST_CONFIG_IDENT); /* Пробросим ошибку */ raise; end EQCONFIG_THOBJ_FORECAST_PRLG; + + /* Финализация исполнения запроса на формирование прогноза технического объекта */ + procedure EQCONFIG_THOBJ_FORECAST_EPLG + ( + NDATASET_IDENT in number, -- Идентификатор буфера данных + NDATASET_CONFIG_IDENT in number, -- Идентификатор буфера описания данных + NREQUEST_CONFIG_IDENT in number, -- Идентификатор буфера описания запроса + NEQCONFIG in number, -- Рег. номер технического объекта + NEQUIPDSCMML in number, -- Рег. номер модели + CFORECAST in clob -- Данные прогноза + ) + is + NEQUIPDSCMMLH PKG_STD.TREF; -- Рег. номер истории запросов модели + BRQ blob; -- Описание параметров запроса на прогноз + begin + /* Считаем параметры сделанного запроса */ + begin + select T.BDATA + into BRQ + from FILE_BUFFER T + where T.IDENT = NREQUEST_CONFIG_IDENT + and T.BDATA is not null; + exception + when NO_DATA_FOUND then + P_EXCEPTION(0, 'Параметры запроса на прогнозирование не определёны.'); + when TOO_MANY_ROWS then + P_EXCEPTION(0, 'Параметры запроса на прогнозирование определёны неоднозначно.'); + end; + /* Добавляем запись истории запросов */ + UDO_PKG_EQUIPDS_BASE.CMMLH_INS(NPRN => NEQUIPDSCMML, + NEQCONFIG => NEQCONFIG, + SRQ_AUTHID => UTILIZER(), + DRQ_DATE => sysdate, + BRQ => BRQ, + NRN => NEQUIPDSCMMLH); + /* Сохраним данные прогноза */ + UDO_PKG_EQUIPDS_BASE.CMMLH_SET_FORECAST(NRN => NEQUIPDSCMMLH, BFORECAST => BASE64_DECODE(LCSRCE => CFORECAST)); + /* Подчистим буферы */ + EQCONFIG_THOBJ_FORECAST_BCLR(NDATASET_IDENT => NDATASET_IDENT, + NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT, + NREQUEST_CONFIG_IDENT => NREQUEST_CONFIG_IDENT); + exception + when others then + /* Подчистим буферы */ + EQCONFIG_THOBJ_FORECAST_BCLRAT(NDATASET_IDENT => NDATASET_IDENT, + NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT, + NREQUEST_CONFIG_IDENT => NREQUEST_CONFIG_IDENT); + /* Пробросим ошибку */ + raise; + end EQCONFIG_THOBJ_FORECAST_EPLG; /* Формирование цвета прогноза для технического объекта */ function EQCONFIG_THOBJ_FORECAST_CLR diff --git a/db/UDO_P_EQCONFIG_DATASET_MAKE.prc b/db/UDO_P_EQCONFIG_DATASET_MAKE.prc index 9f8cff9..58f149f 100644 --- a/db/UDO_P_EQCONFIG_DATASET_MAKE.prc +++ b/db/UDO_P_EQCONFIG_DATASET_MAKE.prc @@ -5,7 +5,8 @@ create or replace procedure UDO_P_EQCONFIG_DATASET_MAKE DBEG in date, -- Дата "С" DEND in date, -- Дата "По" NDATASET_IDENT out number, -- Идентификатор буфера данных - NDATASET_CONFIG_IDENT out number -- Идентификатор буфера описания данных + NDATASET_CONFIG_IDENT out number, -- Идентификатор буфера описания данных + NREQUEST_CONFIG_IDENT out number -- Идентификатор буфера описания запроса ) is begin diff --git a/db/UDO_T_EQUIPDSCMMLH.sql b/db/UDO_T_EQUIPDSCMMLH.sql index fd9dced..7856251 100644 --- a/db/UDO_T_EQUIPDSCMMLH.sql +++ b/db/UDO_T_EQUIPDSCMMLH.sql @@ -15,13 +15,10 @@ create table UDO_T_EQUIPDSCMMLH RQ blob, /* Данные прогноза */ FORECAST blob, - /* Идентификатор очереди обмена */ - EXSQUEUE number(17) default null, /* Ключи */ constraint UDO_C_EQUIPDSCMMLH_RN_PK primary key (RN), constraint UDO_C_EQUIPDSCMMLH_PRN_FK foreign key (PRN) references UDO_T_EQUIPDSCMML(RN), constraint UDO_C_EQUIPDSCMMLH_EQCONFIG_FK foreign key (EQCONFIG) references EQCONFIG(RN), constraint UDO_C_EQUIPDSCMMLH_RQAUTHID_NB check (rtrim(RQ_AUTHID) is not null), - constraint UDO_C_EQUIPDSCMMLH_EXSQUEUE_FK foreign key (EXSQUEUE) references EXSQUEUE(RN), constraint UDO_C_EQUIPDSCMMLH_UN unique (PRN, RQ_AUTHID, RQ_DATE) ); diff --git a/panels/eqs_tech_cond_forecast/forecast_tab.js b/panels/eqs_tech_cond_forecast/forecast_tab.js index a1fa103..b8c20b3 100644 --- a/panels/eqs_tech_cond_forecast/forecast_tab.js +++ b/panels/eqs_tech_cond_forecast/forecast_tab.js @@ -179,13 +179,32 @@ const ForecastTab = ({ onGoToAdmin }) => { callBack: async res => { //Данные подготовлены успешно if (res.success) { + //Проверим наличие необходимых выходных параметров + try { + if (!res.outParameters.NDATASET_IDENT) + throw new Error( + 'Процедура подготовки данных о наработках не вернула идентификатор буфера набора данных (проверьте наличие и значение выходного параметра "NDATASET_IDENT").' + ); + if (!res.outParameters.NDATASET_CONFIG_IDENT) + throw new Error( + 'Процедура подготовки данных о наработках не вернула идентификатор буфера описания набора данных (проверьте наличие и значение выходного параметра "NDATASET_CONFIG_IDENT").' + ); + if (!res.outParameters.NREQUEST_CONFIG_IDENT) + throw new Error( + 'Процедура подготовки данных о наработках не вернула идентификатор буфера параметров запроса на прогнозирование (проверьте наличие и значение выходного параметра "NREQUEST_CONFIG_IDENT").' + ); + } catch (e) { + showMsgErr(e.message); + return; + } //Подготовим запрос к фреймворку прогнозирования const forecastReqData = await executeStored({ stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_PRLG", args: { NEQUIPDSCMML: model.NRN, + NDATASET_IDENT: res.outParameters.NDATASET_IDENT, NDATASET_CONFIG_IDENT: res.outParameters.NDATASET_CONFIG_IDENT, - NDATASET_IDENT: res.outParameters.NDATASET_IDENT + NREQUEST_CONFIG_IDENT: res.outParameters.NREQUEST_CONFIG_IDENT }, tagValueProcessor: (name, value) => (name === "VALUE" ? undefined : value) }); @@ -211,8 +230,7 @@ const ForecastTab = ({ onGoToAdmin }) => { headers: { Authorization: `Basic ${forecastReqData.SAUTH_TOKEN}`, Accept: "*/*", - "Content-Type": "application/json", - "User-Agent": "Parus" + "Content-Type": "application/json" } }); //Обработаем результаты @@ -221,7 +239,7 @@ const ForecastTab = ({ onGoToAdmin }) => { try { responseJson = await response.json(); } catch (e) { - throw new Error("Неожиданный ответ системы прогнозирования: ответ неверного формата!"); + throw new Error("Неожиданный ответ системы прогнозирования: ответ неверного формата."); } if (response) { if (responseJson?.status && responseJson.status == "ERR") @@ -232,6 +250,7 @@ const ForecastTab = ({ onGoToAdmin }) => { args: { NDATASET_IDENT: res.outParameters.NDATASET_IDENT, NDATASET_CONFIG_IDENT: res.outParameters.NDATASET_CONFIG_IDENT, + NREQUEST_CONFIG_IDENT: res.outParameters.NREQUEST_CONFIG_IDENT, NEQCONFIG: techObj.id, NEQUIPDSCMML: model.NRN, CFORECAST: { @@ -243,9 +262,9 @@ const ForecastTab = ({ onGoToAdmin }) => { }); hideLoader(); setRefresh(pv => ({ ...pv, techObjForecastHistList: pv.techObjForecastHistList + 1 })); - } else throw new Error("Неожиданный ответ системы прогнозирования: ответ не содержит данных прогноза!"); - } else throw new Error("Неожиданный ответ системы прогнозирования: ответ не содержит данных!"); - } else throw new Error(`Ошибка (${response.status}) при взаимодейтсвии с системой прогнозирования!`); + } else throw new Error("Неожиданный ответ системы прогнозирования: ответ не содержит данных прогноза."); + } else throw new Error("Неожиданный ответ системы прогнозирования: ответ не содержит данных."); + } else throw new Error(`Ошибка (${response.status}) при взаимодейтсвии с системой прогнозирования.`); } catch (e) { hideLoader(); showMsgErr(e.message);