KIS Z. Руководство разработчика — различия между версиями

Материал из ИбисоПедии
Перейти к: навигация, поиск
 
(не показаны 3 промежуточные версии этого же участника)
Строка 1: Строка 1:
 +
Внимание, это экспорт из файла markodwn "kis-z\client\doc\MarkDown\KIS_Z Руководство разработчика\KIS_Z Руководство разработчика.md"
 +
 +
Картинки смотреть там
 +
 +
__TOC__
  
  
Строка 21: Строка 26:
 
* список системных форм
 
* список системных форм
 
* выполнение SQL скриптов
 
* выполнение SQL скриптов
 
  
 
= Параметры командной строки =
 
= Параметры командной строки =
Строка 74: Строка 78:
  
  
<source >// группа функций: работа с таблицей настроек mm.adj
+
<source >
 +
// группа функций: работа с таблицей настроек mm.adj
 
function GetAdj(ASection: String; AParam: string): String;
 
function GetAdj(ASection: String; AParam: string): String;
 
function GetAdjCashed(ASection: String; AParam: string): String;
 
function GetAdjCashed(ASection: String; AParam: string): String;
Строка 81: Строка 86:
 
procedure SetAdjCashedNoDB(ASection: String; AParam: string; AValue: String);
 
procedure SetAdjCashedNoDB(ASection: String; AParam: string; AValue: String);
 
function DelAdjCashed(ASection: String; AParam: string): String;</source>
 
function DelAdjCashed(ASection: String; AParam: string): String;</source>
 +
=== Сетевые настройки в kis.local.ini ===
 +
 +
Иногда, некоторые глобальные настройки необходимо переопределить для определенных пользователей. Например, адреса подключения к сторонним сервисам. Такие настройки можно определить в файле kis.local.ini
 +
 +
<source >// Читает из файла локальных настроек
 +
function GetAdjFromLocalIni(ASection: String; AParam: string;ADef: String = '0') : String;</source>
 +
=== Локальные предпочтения пользователя  ===
 +
 +
Сохраняются в реестре ('''HKEY''CURRENT''USER\Software\OT\KIS\kis_z''') через модуль '''dmConf'''.
 +
 +
Рекомендуется сохраняться настройки с учетом текущего применённого профиля пользователя:
 +
 +
<source >procedure TfmAuditTablesList.SaveLastPostion;
 +
begin
 +
  if uq1.RecordCount > 0 then
 +
    dmConf.AppStorage.WriteString(RegProfilePreferences + Self.Classname,
 +
      uq1.FieldByName('id').AsString);
 +
 +
end;
 +
</source>
 +
 +
<source >procedure TfmAuditTablesList.LoadLastPostion;
 +
var
 +
  S : String;
 +
begin
 +
  S := dmConf.AppStorage.ReadString(RegProfilePreferences + Self.Classname);
 +
  uq1.Locate('id', S, []);
 +
end;
 +
</source>
 +
Обратите внимание на фунцию RegProfilePreferences, объявленную в модуле dConf
 +
 +
= Структура исходных кодов =
 +
 +
== Правила именования файлов ==
 +
 +
'''Префиксы'''
 +
 +
{|
 +
! префикс
 +
! описание
 +
! Пример
 +
|-
 +
| f
 +
| Модуль содержит TForm
 +
| fEmpList
 +
|-
 +
| d
 +
| Модуль содержит TDatamodul
 +
| dMain, dDept
 +
|-
 +
| u
 +
| unit
 +
|
 +
|}
 +
 +
 +
 +
'''Суффиксы файлов'''
 +
 +
Модули редакторы сущности должны заканчиваться на '''Entity''', например fEmpEntity
 +
 +
Модули списки должны заканчиваться на '''List''', например fEmpList
 +
 +
Модули выбора сущности должны заканчиваться на '''Get''', например fEmpGet
 +
 +
Модули с модальными формами должны заканчиваться на '''Modal''', например fAWPChangeModal
 +
 +
== Расположение файлов ==
 +
 +
== Соглашение об именовании компонентов ==
 +
 +
== Формат комментариев ==
 +
 +
== Системные датамодули ==
 +
 +
=== dmMain ===
 +
 +
В модуле собраны следующие категории процедур
 +
 +
<ul>
 +
<li><p>аутентификация,</p></li>
 +
<li><p>авторизация (проверка прав, профили)</p></li>
 +
<li><p>аудит входа-выхода</p></li>
 +
<li><p>соединение с postgresql , обработка ошибок, мониторинг SQL</p></li>
 +
<li><p>системный каталог postgresql</p>
 +
<pre class="">Внимание, модуль не должен содержать бизнес-логику приложения.    Предполагается что он может быть легко адаптирован под другие проекты</pre></li></ul>
 +
 +
=== dmImages ===
 +
 +
Модуль для работы с изображениями (иконки на кнопках и пр.), скинами и стилями
 +
 +
=== dmConfig ===
 +
 +
процедуры, константы для работы с локальными настройками (в реестер или еще где)
 +
 +
Модуль не должен содержать бизнесс логику приложения и по возможность  может быть быстро адаптирован для работы в другом приложении
 +
 +
=== dmRepControl ===
 +
 +
Репозиторих общих контролов, таких как:
 +
 +
* пол
 +
* разрешено/запрещено
 +
* системный атрибут
 +
 +
Не следует здесь размешать контролы для своих модулей. Делайте свой пользовательский датамодуль. Например, контролы с операциями собраны в dmOper, контролы с отделениями в dDept и т.п.
 +
 +
=== dmMQTT ===
 +
 +
Получение оповещений MQTT
 +
 +
== Функциональные датамодули ==
 +
 +
=== dmDept ===
 +
 +
Невизуальный модуль, который содержит:
 +
 +
* справочные датасеты, связанные с отделениями (отделения, сотрудники, специализации, кабинеты)
 +
* репозиторий контролов:
 +
** комбобокс выбор отделения,
 +
** комбокс выбор подразделения,
 +
** комбобокс выбор профиля
 +
** и т.п.
 +
 +
Singleton используйте dmDept_init
 +
 +
=== dmMdoc ===
 +
 +
Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов для медицинских документов (пока в основном для статкарты). Например справочние датасеты для статкарты: место жительства, результат госпитализации, гражданство, и т.п.
 +
 +
Singleton используйте dmMdoc_init
 +
 +
=== dmNaz ===
 +
 +
Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов связанные с типами назначений
 +
 +
Singleton используйте dmNaz_init
 +
 +
=== dmDiag ===
 +
 +
Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов связанные с типами диагнозов
 +
 +
Singleton используйте dmDiag_init
 +
 +
=== dmOper ===
 +
 +
Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов связанные с Операциями
 +
 +
Singleton используйте dmOper_init
 +
 +
=== dmSickleave ===
 +
 +
Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов связанные с Листками нетрудспособности
 +
 +
Singleton используйте dmSickleave_init
 +
 +
=== dmAmbticket ===
 +
 +
 +
 +
=== Рарзработка своих функциональных датамодулей ===
 +
 +
Экземпляры датамодулей должны создаваться только когда потребуется
 +
 +
== Базовый класс TKISWin и единообразные иконки и горячие клавиши  ==
 +
 +
Этот класс ответственен за одинаковость иконок в dxBarManager и горячих клавиш. Основные формы наследуются от этого класса.
 +
 +
== Типы форм ==
 +
 +
Для пользователя можно выделить следующие типы визуальных форм:
 +
 +
* '''Список''' (наследник от класса TKISWinEntity из модуля KISWIN.Entity.)
 +
* '''Редактор сущности''' (наследник от класса TKISWinList из модуля KISWin.List)
 +
* '''Выбор сущности''' (наследник от класса TKISWinGet из модуля KISWin.Get)
 +
* '''Модальная форма''' (общего предка нет, нужно делать нужно из шаблона)
 +
* '''Главная форма''' (она одна единственная)
 +
* '''Вспомогательные формы''' (например: формы закладки для мед документов, формы простых фильтров для списков)
 +
 +
=== Форма список ===
 +
 +
Класс TKISWinList реализовывает след функционал
 +
 +
* Лента риббон дочится на главную ленту риббон
 +
* При активации деактивации формы, главная форма отображает риббон соответствующей формы
 +
* Вешаеются обработчики на стандартные кнопки &quot;Редактировать&quot;, &quot;Панель поиска&quot;.
 +
* Вешается даблклик на grid / treelist
 +
 +
=== Форма редактор сущности ===
 +
 +
Класс реализовывает следующий функционал
 +
 +
* определятся список модифицируемых датасетов ModifiedDataSet (через переопределение процедуры DefineDataSet)
 +
* Связывает состояние кнопки &quot;Сохранить&quot; с состоянием датасеотов из ModifiedDataSet. Если хоть в одном датасет есть что сохранять, то Enabled=True
 +
* Вешает стандартные обработчики на кнопки &quot;Сохранить&quot; (сохраняются все датасеты из ModifiedDataSet), &quot;Удалить&quot;, &quot;Закрыть&quot;, &quot;И выбрать&quot;
 +
* Формирует Caption формы - в зависимости от идентификатора сушности
 +
* При сохранении данных посылает сообщение FNotifyMessage
 +
* Показывет системные формы по горячим клавишам Ctrl+Shift + L
 +
 +
== Обмен сообщениями между формами ==
 +
 +
Формы посылают глобально всем другим формам уведомления через Postmessage. Список всех констант- сообщений для посылки между формами определен в файле '''uOTMessages'''. Сообщения можно посылать через
 +
 +
= Разработка =
 +
 +
=== Разработка пользовательских форм на основе шаблонов ===
 +
 +
В папке SRCTemplate\Script расположены скрипты для создания следующих типов форм:
 +
 +
* Форма список
 +
* Форма - редактор сущности
 +
* Модальная форма
 +
* Форма выбор
 +
 +
Для создания формы, необходимо в файле &quot;1.bat&quot; раскомментировать нужные строки и задать название новым модулям системы.
 +
 +
Форму список и форму редактор сущности лучше создавать одновременно (тогда сразу же заработают перекрестные ссылки).
 +
 +
== Продвинутый функционал в формах редактороах (Entity) ==
 +
 +
=== Сохранение данных в редакторах (Entity) ===
 +
 +
Если стандартная процедура с последовательными сохранением всех датасетов добавленных в ModifyDataset не подходит, то необходимо переопределить процедуру
 +
 +
<blockquote><code>procedure SaveData; reintroduce;override;</code> <code>...</code> <code>procedure TfmPeopleEntity.SaveData;</code> <code>begin</code> <code>inherited;</code>
 +
 +
<code>dmMain.con.ExecProc('mm.people_set_fio_equally', [EntityID]);</code>
 +
 +
<code>end;</code>
 +
</blockquote>
 +
=== Дополнительные проверки при сохранении ===
 +
 +
procedure CheckData; overload; Virtual;
 +
 +
=== Создание подчиненной сущности ===
 +
 +
=== Рекомендации по открытию подчиненных датасетов ===
 +
 +
=== Выгрузка в SQL ===
 +
 +
По умолчанию TKISWinEntity выгружает в SQL результат работы функции dev.dml_json по главному dataset. Если нужно написать что-то сложнее, то необходимо переопределить функцию GetSQL. См например TfmFileEntity.GetSQL
 +
 +
=== Разделы в ИБ, ТЛ ИБ, статкарте, амблуаторном талоне ===
 +
 +
== Разработка форм-списков ==
 +
 +
== Разработка форм-выбора сущностей ==
 +
 +
== Хелперы для создания элементов интерфеса ==
 +
 +
=== Хелепер для пенели поиска ===
 +
 +
Сейчас это делает KISWINList. Достаточно положить кнопку и назвать ее &quot;Панель поиска&quot;. Но например в модальных формах можно добавить такой функционал самому:
 +
 +
 +
 +
<source >  TOTcxTableViewFindPanelButton.Create(bbFindPanel, tv1);</source>
 +
 +
 +
=== Хелпер для серверного фильтра ===
 +
 +
Связывает кнопку вызова фильтра,панель фильтра, сплиттер
 +
 +
[[File:C:\usr\Zhukov\kis-z\client\doc\MarkDown\KIS_Z Руководство разработчика\img\12. Хелпер серверный фильтр.png|thumb|none]]
 +
 +
# В диазайнер необходимо
 +
 +
* созадать кнопку вызова фильтра (TcxBarButton)
 +
* положить панель фильтра
 +
* положить сплитер (TcxSplitter), связав его с панелью
 +
 +
На onCreate создать хелпер
 +
 +
uOTFilter.TOTFilter.Create(bbFilter, spFilter, bbFilterClose);
 +
 +
=== Хелпер для выбора (добавления) полей в списки ===
 +
 +
[[File:C:\usr\Zhukov\kis-z\client\doc\MarkDown\KIS_Z Руководство разработчика\img\10. Хелпер Выбора полей в списке.png|thumb|none]]
 +
 +
# Объявить переменную:
 +
 +
private  FFieldChoiceForGridButtonHelper : fFieldChoiceForGridByUQModal.TFieldChoiceForGridButtonHelper;
 +
 +
# Дописать создание на FormCreate
 +
 +
FFieldChoiceForGridButtonHelper := fFieldChoiceForGridByUQModal.TFieldChoiceForGridButtonHelper.create(bbField, tv1,4, bbRefreshClick );
 +
 +
# В процедуре формирования запроса RefreshData
 +
 +
<source >// Добавим дополнительные поля</source>
 +
<source >  FFieldChoiceForGridButtonHelper.SQL_Append_additional_Fields(sSelect, sFrom, sWhere );</source>
 +
=== Создание ButtonEdit связанного с формой выбора или редактора сущности ===
 +
 +
[[File:C:\usr\Zhukov\kis-z\client\doc\MarkDown\KIS_Z Руководство разработчика\img\11. Хелпер ButtonEdit редактор.png|thumb|none]]
 +
 +
Убедиться в том что классы выбора/реактора созданы (или создать их с помощь шаблона).
 +
 +
В Дизайнере
 +
 +
# В датасете выбрать поле
 +
# Связать tcxButtonEdit c этим полем
 +
# на FormCreate:
 +
 +
<blockquote>SetaAsIBISRightEdit(bbRght, 'rght_id', nil);
 +
</blockquote>
 +
=== Хелпер выбора периода (дата с, дата по) ===
 +
 +
Связывает контролы TcxDateEdit с выпадающим меню
 +
 +
[[File:C:\usr\Zhukov\kis-z\client\doc\MarkDown\KIS_Z Руководство разработчика\img\13. Хелпер выбора периода.png|thumb|none]]
 +
 +
На FormCreate:
 +
 +
bbOutDT.DropDownMenu :=uPeriodPopup.GetPopupForPeriod(Self,dtFrom, dtTo );
 +
 +
=== Хелпер выбора периода рождения (дети, взрослые) ===
 +
 +
Связывает контролы TcxDateEdit с выпадающим меню
 +
 +
[[File:C:\usr\Zhukov\kis-z\client\doc\MarkDown\KIS_Z Руководство разработчика\img\14. Хелпер выбора периода рождения.png|thumb|none]]
 +
 +
На FormCreate:  bbBirthDropDown.DropDownMenu :=uPeriodPopup.GetPopupForRojd(Self,dtBirthBeg, dtBirthEnd );
 +
 +
== Подключение печатных форм и отчетов ==
 +
 +
== Работа с правами ==
 +
 +
== Модальные формы ==
 +
 +
интерфейс, принципы применения
 +
 +
= Конфигурирование АРМ (начального меню) =
 +
 +
В АРМ разработчика можно настроить начальное меню панели навигации, которое будет доступно пользователю. Для этого заходим в АРМ разработчика (закладка КИС в ленте) и выбираем в панели навигации пункт '''АРМ''':
 +
 +
[[File:C:\usr\Zhukov\kis-z\client\doc\MarkDown\KIS_Z Руководство разработчика\img\15. Настройка АРМ.png|thumb|none]]
 +
 +
 +
 +
= Разработка отчетов =
 +
 +
== Печатные формы Fastreport ==
 +
 +
== ReportWorkShop ==
 +
 +
= Аудит данных (история изменения) =
 +
 +
На каждую таблицу триггерами может поддреживаться своя таблица истории изменения данных в схеме audit.
 +
 +
== Включение / выключение ==
 +
 +
select audit.enable''log('mm', 'emp')  select audit.disable''log('mm', 'emp')
 +
 +
== Настройка журнала аудита и архивные журналы ==
 +
 +
Для больших журналов есть возможность разбить на оперативный и архивный журнал. Архивный журнал будет располагаться в схеме audit2.
 +
 +
== Просмотр изменений по основной таблице конкретной сущности ==
 +
 +
За отображение журнала изменений отвечает модуль fChangeHistoryLIST. Для вызова журнал изменений по конкретной сущности используйте следующий код:
 +
 +
<source >fChangeHistoryLIST.ShowChangeHistoryByTable('mm','emp',EntityID,'id');</source>
 +
== Просмотр изменений по сводному журналу. ==
 +
 +
# Сначала нужно скофигурировать сводный журнал через интерфейс
 +
 +
<source >fAuditUnionHistoryLIST.ShowUnionChangeHistoryByEntity(1, GUIDNoBrace(Self.EntityID));</source>
 +
где 1- это константа, определяющая сводный журнал
 +
 +
= Обновление системы =
 +
 +
== Формат обновления ==
 +
 +
== Порядок применения обновления ==
 +
 +
== Создание обновлений БД ==
 +
 +
== Создание обновлений метаданных ThinkEHR ==
 +
 +
= Настройщик соответствий справочников с внешними системами =
 +
 +
= Рекомендации по пользовательскому интерфейсу =
 +
 +
Подписи к кнопка должны быть глаголами в повелительном наклонении совершенного вида:
 +
 +
* Выполнить
 +
* Сохранить
 +
* Редактировать
 +
* Октрыть
 +
 +
Или Существительными ед числа
 +
 +
* Статкарта
 +
* ИБ
 +
 +
= Языковая локализация =
 +
 +
Используется компонент Devexpress TcxLocalizer (лежит в модуе dConf). Файл с языковым ресурсам называется Localization.lng и должен лежать рядом с exe. Это обычный текстовый файл, но его можно править с помощью утилиты Localizer Editor (&quot;C:\Lib\DevExpress 18.1.9\ExpressLibrary\cxLocalizerEditor.exe&quot; )
 +
 +
Пример как правильно получить значение локализованной строки:  cxGetResourceString(@cxSFilterOperatorNotBetween); Более подробно описана в справке &quot;C:\Lib\DevExpress 18.1.9\ExpressLibrary\Help\ExpressCrossPlatformLibrary.chm&quot;
 +
 +
= Сборник рецептов =
 +
 +
= Настройка среды Delphi =
 +
 +
= Компоненты и документация =
 +
 +
== Embarcadero Delphi 10.3 ==
 +
 +
== Devexpress VCL 18.1 ==
 +
 +
== UniDac VCL 7.4 ==
 +
 +
== FastReprot 6.3 ==
 +
 +
== JEDI ==
 +
 +
== Postgresql ==
 +
 +
Начинать с документации https://postgrespro.ru/docs/postgresql/10/index, все что ниже, это дополнительное чтение
 +
 +
=== Книги ===
 +
 +
Работа с PostgreSQL настройка и масштабирование http://postgresql.leopard.in.ua/
 +
 +
=== Что нового ===
 +
 +
* PostgreSQL 9.3 Что нового http://habrahabr.ru/post/195898/
 +
* PostgreSQL 9.4 Что нового? http://habrahabr.ru/post/234909/
 +
* PostgreSQL 9.5: что нового? Часть 1. INSERT… ON CONFLICT DO NOTHING/UPDATE и ROW LEVEL SECURITY https://habr.com/post/264281/
 +
* PostgreSQL 9.5: что нового? Часть 2. TABLESAMPLE https://habr.com/post/266759/
 +
* PostgreSQL 9.5: что нового? Часть 3. GROUPING SETS, CUBE, ROLLUP https://habr.com/post/269849/
 +
* Секционирование в PostgreSQL 10 и не только https://habr.com/company/postgrespro/blog/353472/
 +
* Как ускорили PostgreSQL 10 https://habr.com/company/postgrespro/blog/352144/
 +
* Что нового в PostgreSQL 11: JSONB-трансформы https://habr.com/company/postgrespro/blog/354264/
 +
* Что нового в PostgreSQL 11: INCLUDE-индексы https://habr.com/company/postgrespro/blog/353126/
 +
 +
=== Оптимизация запросов ===
 +
 +
* Оптимизация запросов. Основы EXPLAIN в PostgreSQL https://habr.com/post/203320/
 +
* Оптимизация запросов. Основы EXPLAIN в PostgreSQL (часть 2) http://habrahabr.ru/post/203386/
 +
* Оптимизация запросов. Основы EXPLAIN в PostgreSQL (часть 3) https://habr.com/post/203484/
 +
 +
=== Цикл статей Индексы в postgersql: ===
 +
 +
* Индексы в postgresql -1 (механизм индексирования) https://habrahabr.ru/company/postgrespro/blog/326096/
 +
* Индексы в postgresql - 2 https://habr.com/company/postgrespro/blog/326106/
 +
* Индексы в postgresql - 3 https://habr.com/company/postgrespro/blog/328280/
 +
* Индексы в postgresql - 4 (Btree) https://habr.com/company/postgrespro/blog/330544/
 +
* Индексы в postgresql - 5 (Gist) https://habr.com/company/postgrespro/blog/333878/
 +
* Индексы в postgresql - 6 (SP-GIST) https://habr.com/company/postgrespro/blog/337502/
 +
* Индексы в postgresql - 7 (GIN) https://habr.com/company/postgrespro/blog/340978/
 +
* Индексы в postgresql - 8 (джин в ром) https://habr.com/company/postgrespro/blog/343488/
 +
* Индексы в postgresql - 9 (BRIN-индексы) https://habr.com/company/postgrespro/blog/346460/
 +
* Индексы в postgresql - 10 (bloom) https://habr.com/company/postgrespro/blog/349224/
 +
* Производительность запросов в PostgreSQL – шаг за шагом Илья Космодемьянский http://highload.guide/blog/query''performance''postgreSQL.html
 +
* Understanding EXPLAIN (pdf на 42 страницы) https://www.dalibo.org/''media/understanding''explain.pdf SQL запросы
 +
* Как посчитать всё на свете одним SQL-запросом (Очень рекомендую). Оконные функции PostgreSQL https://habr.com/post/268983/
 +
* И снова о рекурсивных запросах https://habr.com/company/postgrespro/blog/318398/
 +
 +
=== Администрирование ===
 +
 +
* Илья Космодемьянский — Внутреннее устройство PostgreSQL для практикующих инженеров https://youtu.be/jGOkSerUPw4
 +
* PostgreSQL: архитектура, настройка и оптимизация https://www.youtube.com/watch?v=oSlS54Ou7Ms
 +
* Как PostgreSQL работает с диском, Илья Космодемьянский PostgreSQL Consulting https://www.youtube.com/watch?v=NY-9HUnmR6c
 +
* Администрирование PostgreSQL 9.4 (базовый курс). Postgres professional | Тверь 16-18 декабря 2015 https://www.youtube.com/playlist?list=PLaFqU3KCWw6KzGwUubZm-9-vKsi6vh5qC
 +
* DBA 2. «Администрирование PostgreSQL 9.5. Расширенный курс» Postgres professional https://www.youtube.com/watch?v=iODeKnTD1kA&amp;list=PLaFqU3KCWw6JgufXBiW4dEB2-tDpmOXPH
 +
* Как не потерять данные в PostgreSQL https://habr.com/post/197742/
 +
 +
=== Разное ===
 +
 +
Презентация сравнение с другими SQL http://www.slideshare.net/MarkusWinand/modern-sql (Презентация недоступна) и в целом сайт https://modern-sql.com/
 +
 +
* трех минутный тест как хорошо вы знаете индексы в postgresql (а-а ссылка потерялась!!)
 +
* Блог на сайте https://postgrespro.ru/blog/pgsql. Большинство из перечисленных здесь ссылок есть
 +
 +
[[Категория:Руководство программиста KIS]][[Категория:Руководство программиста KIS_Z]]

Текущая версия на 16:37, 8 августа 2019

Внимание, это экспорт из файла markodwn "kis-z\client\doc\MarkDown\KIS_Z Руководство разработчика\KIS_Z Руководство разработчика.md"

Картинки смотреть там

Содержание


Разработка БД

Описание будет в отдельном документе. Разделы:

  • Соглашение об именовании
  • Функция dev.do_all_ok

Инструменты разработчика

  • Devar dbMonitor - мониторинг SQL, Также можно отправить любое свое сообщение (см справку по TuniMonitor)
  • Во время работы приложения можно получить вызвать окно системной информации нажав комбинацию клавишу ThinkEHR. Из этого окна можно вызвать инспектор объектов формы, нажав комбинацию клавиш Ctrl+Shift+I. Здесь можно увидеть все датасеты, и статус, и данных в них
  • окно информации о непредвиденной ошибке. Если ошибка не обработана, то появиться окно в котором можно увидеть полный CallStack программы, загруженные модули и т.п.
  • секция DEBUG
  • логирование CodeSITE. См https://www.webdelphi.ru/2011/11/obzor-instrumenta-codesite/ и сецию debug файла kis.ini
  • свое логирование в папку LOG (см модуль KIS.FileUtils и константу cnlogdir)
  • выгрузка сущностей в SQL
  • редактор АРМ
  • редактор системных запросов
  • список системных форм
  • выполнение SQL скриптов

Параметры командной строки

Все параметры регистронезависимы

  • /USER=<имя пользователя> - пользователь (чтобы не набирать каждый раз)
  • /PASSWORD=<пароль> - пароль
  • /NOEHR - запуск без подключения к Think!EHR
  • /NOUPDATE - запуск без процедуры обновления локальных файлов
  • /NOMQTT -- без подключения к брокеру MQTT
  • /NAVBARHIDE - скрывает панель навигации
  • /AWP=<AWP_ID> - запускает нужный АРМ (если есть права). GUID без кавычек в фигурных скобках
  • /FORM=<имя класса формы> - сразу открывает нужную форму -список (специально для разработчика).
  • /SKIN=<имя скина> - имя скина по умолчанию
  • /WinEntityClass=<EntityID> - запуск формы редактора сущности
  • /NAVBARHIDE -- запуск со скрытой панелью навигации
  • /RIBBON_HIDETABGroup -- скрыть закладки ленты
  • /WIDTH=<xxx> ширина главного окна
  • /HEIGHT=<xxx> высота главного окна

Устройство платформы

Архитектура

Подсистема безопасности

Настройки системы

Основные принципы

  • настройка подключения к БД храниться в файле kis.ini
  • все остальные настройки, необходимые для работы системы хранятся в разделах mm.adj
  • для особенной конфигурации клиента (как правило сетевой) существует файл kis.local.ini, в котором существуют разделы перекрывающие соответствующие параметры mm.adj

Файл подключения kis.ini

[Postgresql] server=192.168.1.16 port=7432 database=emiac1 sslmode

[Debug] MEMORYLEAK=TRUE Выводить сообщения об утечки памяти EXCEPTIONSHOW=TRUE Показывать исключения CodeSite = True - включает посылку сообщений CodeSite CodeSiteLogFile = True - сообщения CodeSite Будут записаны в файл (имя будет совпадать с именем exe)

Глобальные настройки системы mm.adj

Глобальные настройки системы определяют поведение системы в целом и одинаковые для всех пользователей системы

Редактировать можно через АРМ Администратор -> глобальные настройки. По каждой настройке можно сразу посмотреть журнал изменения.

Прочитанные настройки системы можно увидеть через: Параметры- Параметры КИС

Клиент (kis_z) когда нужно считывает настройку и помещает ее в кэш. Настройка будет сохранена в локальном кэше до конца сеанса (пока kis_z не закроют)


// группа функций: работа с таблицей настроек mm.adj
function GetAdj(ASection: String; AParam: string): String;
function GetAdjCashed(ASection: String; AParam: string): String;
function GetAdjCashedDef(ASection: String; AParam: String; ADef: String = '0'): String;
procedure SetAdjCashed(ASection: String; AParam: string; AValue: String);
procedure SetAdjCashedNoDB(ASection: String; AParam: string; AValue: String);
function DelAdjCashed(ASection: String; AParam: string): String;

Сетевые настройки в kis.local.ini

Иногда, некоторые глобальные настройки необходимо переопределить для определенных пользователей. Например, адреса подключения к сторонним сервисам. Такие настройки можно определить в файле kis.local.ini

// Читает из файла локальных настроек
function GetAdjFromLocalIni(ASection: String; AParam: string;ADef: String = '0') : String;

Локальные предпочтения пользователя

Сохраняются в реестре (HKEYCURRENTUSER\Software\OT\KIS\kis_z) через модуль dmConf.

Рекомендуется сохраняться настройки с учетом текущего применённого профиля пользователя:

procedure TfmAuditTablesList.SaveLastPostion;
begin
  if uq1.RecordCount > 0 then
    dmConf.AppStorage.WriteString(RegProfilePreferences + Self.Classname,
      uq1.FieldByName('id').AsString);

end;
procedure TfmAuditTablesList.LoadLastPostion;
var
  S : String;
begin
  S := dmConf.AppStorage.ReadString(RegProfilePreferences + Self.Classname);
  uq1.Locate('id', S, []);
end;

Обратите внимание на фунцию RegProfilePreferences, объявленную в модуле dConf

Структура исходных кодов

Правила именования файлов

Префиксы

префикс описание Пример
f Модуль содержит TForm fEmpList
d Модуль содержит TDatamodul dMain, dDept
u unit


Суффиксы файлов

Модули редакторы сущности должны заканчиваться на Entity, например fEmpEntity

Модули списки должны заканчиваться на List, например fEmpList

Модули выбора сущности должны заканчиваться на Get, например fEmpGet

Модули с модальными формами должны заканчиваться на Modal, например fAWPChangeModal

Расположение файлов

Соглашение об именовании компонентов

Формат комментариев

Системные датамодули

dmMain

В модуле собраны следующие категории процедур

  • аутентификация,

  • авторизация (проверка прав, профили)

  • аудит входа-выхода

  • соединение с postgresql , обработка ошибок, мониторинг SQL

  • системный каталог postgresql

    Внимание, модуль не должен содержать бизнес-логику приложения.    Предполагается что он может быть легко адаптирован под другие проекты

dmImages

Модуль для работы с изображениями (иконки на кнопках и пр.), скинами и стилями

dmConfig

процедуры, константы для работы с локальными настройками (в реестер или еще где)

Модуль не должен содержать бизнесс логику приложения и по возможность  может быть быстро адаптирован для работы в другом приложении

dmRepControl

Репозиторих общих контролов, таких как:

  • пол
  • разрешено/запрещено
  • системный атрибут

Не следует здесь размешать контролы для своих модулей. Делайте свой пользовательский датамодуль. Например, контролы с операциями собраны в dmOper, контролы с отделениями в dDept и т.п.

dmMQTT

Получение оповещений MQTT

Функциональные датамодули

dmDept

Невизуальный модуль, который содержит:

  • справочные датасеты, связанные с отделениями (отделения, сотрудники, специализации, кабинеты)
  • репозиторий контролов:
    • комбобокс выбор отделения,
    • комбокс выбор подразделения,
    • комбобокс выбор профиля
    • и т.п.

Singleton используйте dmDept_init

dmMdoc

Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов для медицинских документов (пока в основном для статкарты). Например справочние датасеты для статкарты: место жительства, результат госпитализации, гражданство, и т.п.

Singleton используйте dmMdoc_init

dmNaz

Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов связанные с типами назначений

Singleton используйте dmNaz_init

dmDiag

Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов связанные с типами диагнозов

Singleton используйте dmDiag_init

dmOper

Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов связанные с Операциями

Singleton используйте dmOper_init

dmSickleave

Невизуальный датамодуль, которые содержить справочные Dataset, и репозитарий контролов связанные с Листками нетрудспособности

Singleton используйте dmSickleave_init

dmAmbticket

Рарзработка своих функциональных датамодулей

Экземпляры датамодулей должны создаваться только когда потребуется

Базовый класс TKISWin и единообразные иконки и горячие клавиши

Этот класс ответственен за одинаковость иконок в dxBarManager и горячих клавиш. Основные формы наследуются от этого класса.

Типы форм

Для пользователя можно выделить следующие типы визуальных форм:

  • Список (наследник от класса TKISWinEntity из модуля KISWIN.Entity.)
  • Редактор сущности (наследник от класса TKISWinList из модуля KISWin.List)
  • Выбор сущности (наследник от класса TKISWinGet из модуля KISWin.Get)
  • Модальная форма (общего предка нет, нужно делать нужно из шаблона)
  • Главная форма (она одна единственная)
  • Вспомогательные формы (например: формы закладки для мед документов, формы простых фильтров для списков)

Форма список

Класс TKISWinList реализовывает след функционал

  • Лента риббон дочится на главную ленту риббон
  • При активации деактивации формы, главная форма отображает риббон соответствующей формы
  • Вешаеются обработчики на стандартные кнопки "Редактировать", "Панель поиска".
  • Вешается даблклик на grid / treelist

Форма редактор сущности

Класс реализовывает следующий функционал

  • определятся список модифицируемых датасетов ModifiedDataSet (через переопределение процедуры DefineDataSet)
  • Связывает состояние кнопки "Сохранить" с состоянием датасеотов из ModifiedDataSet. Если хоть в одном датасет есть что сохранять, то Enabled=True
  • Вешает стандартные обработчики на кнопки "Сохранить" (сохраняются все датасеты из ModifiedDataSet), "Удалить", "Закрыть", "И выбрать"
  • Формирует Caption формы - в зависимости от идентификатора сушности
  • При сохранении данных посылает сообщение FNotifyMessage
  • Показывет системные формы по горячим клавишам Ctrl+Shift + L

Обмен сообщениями между формами

Формы посылают глобально всем другим формам уведомления через Postmessage. Список всех констант- сообщений для посылки между формами определен в файле uOTMessages. Сообщения можно посылать через

Разработка

Разработка пользовательских форм на основе шаблонов

В папке SRCTemplate\Script расположены скрипты для создания следующих типов форм:

  • Форма список
  • Форма - редактор сущности
  • Модальная форма
  • Форма выбор

Для создания формы, необходимо в файле "1.bat" раскомментировать нужные строки и задать название новым модулям системы.

Форму список и форму редактор сущности лучше создавать одновременно (тогда сразу же заработают перекрестные ссылки).

Продвинутый функционал в формах редактороах (Entity)

Сохранение данных в редакторах (Entity)

Если стандартная процедура с последовательными сохранением всех датасетов добавленных в ModifyDataset не подходит, то необходимо переопределить процедуру

procedure SaveData; reintroduce;override; ... procedure TfmPeopleEntity.SaveData; begin inherited;

dmMain.con.ExecProc('mm.people_set_fio_equally', [EntityID]);

end;

Дополнительные проверки при сохранении

procedure CheckData; overload; Virtual;

Создание подчиненной сущности

Рекомендации по открытию подчиненных датасетов

Выгрузка в SQL

По умолчанию TKISWinEntity выгружает в SQL результат работы функции dev.dml_json по главному dataset. Если нужно написать что-то сложнее, то необходимо переопределить функцию GetSQL. См например TfmFileEntity.GetSQL

Разделы в ИБ, ТЛ ИБ, статкарте, амблуаторном талоне

Разработка форм-списков

Разработка форм-выбора сущностей

Хелперы для создания элементов интерфеса

Хелепер для пенели поиска

Сейчас это делает KISWINList. Достаточно положить кнопку и назвать ее "Панель поиска". Но например в модальных формах можно добавить такой функционал самому:


  TOTcxTableViewFindPanelButton.Create(bbFindPanel, tv1);


Хелпер для серверного фильтра

Связывает кнопку вызова фильтра,панель фильтра, сплиттер

  1. В диазайнер необходимо
  • созадать кнопку вызова фильтра (TcxBarButton)
  • положить панель фильтра
  • положить сплитер (TcxSplitter), связав его с панелью

На onCreate создать хелпер

uOTFilter.TOTFilter.Create(bbFilter, spFilter, bbFilterClose);

Хелпер для выбора (добавления) полей в списки

  1. Объявить переменную:
private  FFieldChoiceForGridButtonHelper : fFieldChoiceForGridByUQModal.TFieldChoiceForGridButtonHelper;
  1. Дописать создание на FormCreate
FFieldChoiceForGridButtonHelper := fFieldChoiceForGridByUQModal.TFieldChoiceForGridButtonHelper.create(bbField, tv1,4, bbRefreshClick );
  1. В процедуре формирования запроса RefreshData
// Добавим дополнительные поля
  FFieldChoiceForGridButtonHelper.SQL_Append_additional_Fields(sSelect, sFrom, sWhere );

Создание ButtonEdit связанного с формой выбора или редактора сущности

Убедиться в том что классы выбора/реактора созданы (или создать их с помощь шаблона).

В Дизайнере

  1. В датасете выбрать поле
  2. Связать tcxButtonEdit c этим полем
  3. на FormCreate:
SetaAsIBISRightEdit(bbRght, 'rght_id', nil);

Хелпер выбора периода (дата с, дата по)

Связывает контролы TcxDateEdit с выпадающим меню

На FormCreate:

bbOutDT.DropDownMenu :=uPeriodPopup.GetPopupForPeriod(Self,dtFrom, dtTo );

Хелпер выбора периода рождения (дети, взрослые)

Связывает контролы TcxDateEdit с выпадающим меню

На FormCreate: bbBirthDropDown.DropDownMenu :=uPeriodPopup.GetPopupForRojd(Self,dtBirthBeg, dtBirthEnd );

Подключение печатных форм и отчетов

Работа с правами

Модальные формы

интерфейс, принципы применения

Конфигурирование АРМ (начального меню)

В АРМ разработчика можно настроить начальное меню панели навигации, которое будет доступно пользователю. Для этого заходим в АРМ разработчика (закладка КИС в ленте) и выбираем в панели навигации пункт АРМ:


Разработка отчетов

Печатные формы Fastreport

ReportWorkShop

Аудит данных (история изменения)

На каждую таблицу триггерами может поддреживаться своя таблица истории изменения данных в схеме audit.

Включение / выключение

select audit.enablelog('mm', 'emp')  select audit.disablelog('mm', 'emp')

Настройка журнала аудита и архивные журналы

Для больших журналов есть возможность разбить на оперативный и архивный журнал. Архивный журнал будет располагаться в схеме audit2.

Просмотр изменений по основной таблице конкретной сущности

За отображение журнала изменений отвечает модуль fChangeHistoryLIST. Для вызова журнал изменений по конкретной сущности используйте следующий код:

fChangeHistoryLIST.ShowChangeHistoryByTable('mm','emp',EntityID,'id');

Просмотр изменений по сводному журналу.

  1. Сначала нужно скофигурировать сводный журнал через интерфейс
fAuditUnionHistoryLIST.ShowUnionChangeHistoryByEntity(1, GUIDNoBrace(Self.EntityID));

где 1- это константа, определяющая сводный журнал

Обновление системы

Формат обновления

Порядок применения обновления

Создание обновлений БД

Создание обновлений метаданных ThinkEHR

Настройщик соответствий справочников с внешними системами

Рекомендации по пользовательскому интерфейсу

Подписи к кнопка должны быть глаголами в повелительном наклонении совершенного вида:

  • Выполнить
  • Сохранить
  • Редактировать
  • Октрыть

Или Существительными ед числа

  • Статкарта
  • ИБ

Языковая локализация

Используется компонент Devexpress TcxLocalizer (лежит в модуе dConf). Файл с языковым ресурсам называется Localization.lng и должен лежать рядом с exe. Это обычный текстовый файл, но его можно править с помощью утилиты Localizer Editor ("C:\Lib\DevExpress 18.1.9\ExpressLibrary\cxLocalizerEditor.exe" )

Пример как правильно получить значение локализованной строки: cxGetResourceString(@cxSFilterOperatorNotBetween); Более подробно описана в справке "C:\Lib\DevExpress 18.1.9\ExpressLibrary\Help\ExpressCrossPlatformLibrary.chm"

Сборник рецептов

Настройка среды Delphi

Компоненты и документация

Embarcadero Delphi 10.3

Devexpress VCL 18.1

UniDac VCL 7.4

FastReprot 6.3

JEDI

Postgresql

Начинать с документации https://postgrespro.ru/docs/postgresql/10/index, все что ниже, это дополнительное чтение

Книги

Работа с PostgreSQL настройка и масштабирование http://postgresql.leopard.in.ua/

Что нового

Оптимизация запросов

Цикл статей Индексы в postgersql:

Администрирование

Разное

Презентация сравнение с другими SQL http://www.slideshare.net/MarkusWinand/modern-sql (Презентация недоступна) и в целом сайт https://modern-sql.com/

  • трех минутный тест как хорошо вы знаете индексы в postgresql (а-а ссылка потерялась!!)
  • Блог на сайте https://postgrespro.ru/blog/pgsql. Большинство из перечисленных здесь ссылок есть