Разработка программной системы автоматизации подбора сотрудников в IT-компаниях

Анализ предметной области подбора персонала разрабатываемой системы, процесс формализации требований и автоматизируемые бизнес-процессы. Проектирование поведения системы, модели данных, проектирование нейросети для определения подходящих кандидатов.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 01.12.2019
Размер файла 4,7 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Реализация сбора данных через веб_скрапинг обуславливает необходимость для администраторов вести учет веб-сайтов, с которых будет выполняться сбор данных. Таким образом, можно выделить дополнительную сущность «Веб_источник», основными элементами которой будут уникальный для системы идентификатор, название сайта, а также названия CSS_селекторов, из которых будут забираться основные данные. Веб_сайт с данными о пользовательских резюме можно разделить на два рассматриваемых блока: страница со списком резюме и страница просмотра резюме. На первой странице в качестве основных рассматриваемых селекторов можно выделить три класса: класс, выводящий общее число найденных резюме, класс, отвечающий за отображение списка найденных резюме, и класс, содержащий элемента этого списка. На странице просмотра резюме важными для рассмотрения элементами являются блоки с информацией о пользователе, включая его изображение, на основе которой будет генерироваться пользователь, а также блоки, содержащие информацию о должности, на которую претендует кандидат, ожидаемая зарплата, имеющиеся опыт работы и образования, изученные языки, опыт вождения и ключевые навыки. Для данных блоков можно выделить еще одну сущность «Селектор», которая будет связана с «Веб-источником» в связи один ко многим и будет содержать идентификатор сущности, название селектора и его тип.

Основываясь на выполненном анализе предметной области была спроектирована концептуальная модель данных в нотации диаграммы «Сущность-связь», которая представлена на рисунке 2.2.

Рисунок 2.2. Концептуальная модель системы HR Helper в нотации ERD

Хранение информации о нейросетях, их элементах и используемых множествах является также важным элементом системы для подбора персонала с помощью машинного анализа данных. Так как для использования нейронной сети ее необходимо первоначально обучить и протестировать на больших массивах данных было принято решение о создании дополнительной базы данных.

В данной БД должна храниться информация о нейросети, а именно с какой вакансией данная нейросеть связанна и является ли она обученной. Также важно хранить информацию о нейронах, которые будут применяться для реализации анализа данных. Для нейронов важной информацией является тип нейрона (к какому элементу вакансии он относится, является ли данный нейрон частью входного слоя, скрытого или выходного), а также вес данного нейрона в процессе выполнения анализа и его кодировка, которую можно задать с помощью параметров нижняя граница, верхняя граница и шаг. Связывающим звеном между сущностями «Нейрон» и «Нейросеть» можно выделить отдельную сущность «Слой», для которой важными атрибутами являются тип слоя (входной, скрытый или выходной), а также порядковый номер в цепочке слоев. Сущность «Нейросеть» связана с сущностью «Слой» в отношении один ко многим, т.е. у одной нейросети может быть несколько слоев. Аналогично сущность «Слой» связывается с сущностью «Нейрон», т.к. в одном слое может быть несколько нейронов.

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

Поэтому для разрабатываемой схемы данных необходимо добавить сущность «Множество» и ее «Элемент». Для первой сущности основным используемым атрибутом является тип этого множества (обучающее, тестовое или экспериментальное, то есть основанное на реальных данных). Сущность элемент является сборником экземпляров нейронов, применяемых для вычисления результата.

Таким образом добавляется 3 сущности в модель данных для нейросетей: «Множество», «Элемент множества» и «Экземпляр нейрона», связанные друг с другом последовательно связью один ко многим. Сущность «Экземпляр нейрона» связывается с «Нейроном» в отношении многие к одному, т.к. у одного нейрона может быть множество экземпляров. Разработанная концептуальная модель данных для работы с нейросетями представлена на рисунке 2.3.

Рисунок 2.3. Концептуальная модель данных для работы с нейросетями

2.3 Описание поведения системы HR Helper

Основываясь на результатах анализа предметной области, выявленных требованиях и построенных диаграммах активностей, необходимо определить логическую структуру и поведение системы автоматизированного подбора персонала в IT-компаниях. Для этого необходимо построить диаграммы последовательностей в нотации UML [6]. С помощью диаграмм данного типа можно выявить основные компоненты разрабатываемой системы и операции, которые эти компоненты выполняют.

Диаграмма последовательностей «Создание вакансии» представлена на рисунке 2.4. Данная диаграмма позволяет визуализировать порядок выполнения действий и обмена сообщений между различными объектами системы.

В данной и в остальных диаграммах используются объекты типа hrh_client, hrh_server и hrh_counter. Данные типы характеризуют модули, в которых эти объекты используются. Так hrh_client обозначает модуль front-end приложения, hrh_server - back-end компонента (или сервер). Модуль hrh_counter предназначен для создания нейросетей и заполнения нейросетевых обучающих и тестовых множеств. В следующих диаграммах последовательностей будут использоваться также типы hrh_collector (модуль сбора данных в приложении) и hrh_analyzer (модуль сопоставления вакансий и резюме с помощью обученных нейросетей).

Рисунок 2.4. Диаграмма последовательностей «Создание вакансии»

Описание поведения системы и взаимодействие различных ее компонент в процессе обучения и тестирования нейросети представлено на рисунке 2.5.

Рисунок 2.5. Диаграмма последовательностей «Обучение и тестирование нейросети»

В данном случае обучение нейросети выполняется с помощью модуля hrh_analyzer. Однако данный модуль также применяется для принятия решений при сопоставлении вакансии и резюме. Поведение системы во время выполнения данного процесса описано на рисунке 2.6.

Рисунок 2.6. Диаграмма последовательностей «Сопоставление вакансии и резюме»

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

Рисунок 2.7. Диаграмма последовательностей «Сбор данных»

Рисунок 2.8 представляет диаграмму, описывающую процесс удаления вакансии и соответствующей ей нейросети из БД.

Рисунок 2.8. Диаграмма последовательностей «Удаление вакансии»

Для бизнес-процессов «Идентификация», «Регистрация», «Передача данных о кандидатах», «Учет данных в системе», «Импорт данных», «Импорт резюме», «Импорт вакансии», «Создание резюме», «Экспорт резюме кандидата», «Отслеживание действий пользователей», «Формирование статистических отчетов», «Изменение статуса кандидата», «Экспорт результатов сопоставления», «Генерация вакансии», «Очистка неактуальных данных», «Скачивание руководства пользователя» были созданы диаграммы последовательностей, которые представлены на рисунках B.15-B.29 (см. прил. B).

2.4 Проектирование классов системы HR Helper

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

На уровне серверной части системы HR Helper необходимо реализовать взаимодействие между системой и базой данных. Для этого для каждой сущности из модели данных будет создан репозиторий [29], выполняющий основные операции, такие как вывод списка объектов, получение, добавление, изменение и удаление объекта.

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

1. AccountRepository - репозиторий для работы с пользовательскими аккаунтами, позволяющий получить, создать, изменить и удалить пользователя из системы.

2. AdminRepository - репозиторий для работы с пользователями с ролью «админстратор».

3. ApplicantRepository - репозиторий для работы с пользователями с ролью «соискатель».

4. CompanyRepository - репозиторий для работы с пользователями с ролью «работодатель».

5. VacancyRepository - репозиторий для работы с вакансиями работодателей.

6. ResumeRepository - репозиторий для работы с резюме соискателей.

7. ReportRepository - репозиторий для работы с отчетами по сопоставлению вакансий с резюме.

8. MatchRepository - репозиторий для работы с сопоставлениями вакансий и резюме.

9. SkillRepository - репозиторий для работы с навыками, указываемыми в вакансиях и резюме.

10. TokenRepository - репозиторий для работы с пользовательскими токенами (для осуществления авторизации пользователей в системе).

11. UserActionRepository - репозиторий для работы с пользовательскими действиями.

12. ResumeSkillRepository - репозиторий для работы со связями между резюме и навыками пользователей.

13. VacancySkillRepository - репозиторий для работы со связями между вакансиями и навыками пользователей.

На основе выявленных репозиториев была составлена диаграмма классов [6], представленная на рисунке 2.9. На диаграмме присутствует класс «MainDBContainer», который реализует хранилище всех репозиториев, взаимодействующих с основной базой данных.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Рисунок 2.9. Диаграмма классов для репозиториев основной базы данных

Для классов «нейросетевой» базы данных были также разработаны следующие репозитории:

1. NetworkRepository - репозиторий для работы с искусственными нейронными сетями.

2. LayerRepository - репозиторий для работы со слоями искусственных нейронных сетей.

3. NeuronRepository - репозиторий для работы с нейронами.

4. PlentyRepository - репозиторий для работы с множествами элементов для обучения, тестирования и т.д.

5. PlentyElementRepository - репозиторий для работы с элементами множеств.

6. NeuronInstanceRepository - репозиторий для работы с экземплярами нейронов в элементах множеств.

На основе выявленных репозиториев для «нейросетевой» базы данных была составлена диаграмма классов, представленная на рисунке 2.10. Класс «NeuroDBContainer» аналогично реализует хранилище репозиториев «нейросетевой» базы данных.

Рисунок 2.10. Диаграмма классов для репозиториев «нейросетевой» базы данных

При обмене данных между серверной и клиентской частью приложения, как правило, возникает необходимость неполной передачи полей объекта, или наоборот, передачи дополнительных полей. Для осуществления передачи такого типа был применен паттерн проектирования «Data Transfer Object» (далее DTO) [29], который применяется для передачи данных между подсистемами приложения. Для всех классов, реализующих данный паттерн проектирования, был создан родительский класс BaseDTO, который содержит два поля: ResponseStatus (отображает результат выполнения операции) и ResponseError (отображает сообщение, которое должен увидеть пользователь при неудачном выполнении операции).

Для классов основной базы данных были спроектированы следующие классы, реализующие паттерн DTO:

1. Account DTO - вспомогательные классы пользовательских аккаунтов

1.1. AccountFull - класс, предназначенный для вывода информации о пользователе с его изображением.

1.2. AccountInfo - класс, предназначенный для вывода информации о пользователе с его ролью в системе.

1.3. AccountLoginPassword - класс, применяемый при идентификации пользователя в системе.

1.4. AccountLoginPasswordFIO - класс, применяемый при создании пользователя в системе.

1.5. AccountPasswordChange - класс, применяемый при изменении пароля пользователя в системе.

1.6. AccountPicture - класс, применяемый при изменении изображения пользователя в системе.

1.7. AccountToken - класс, возвращаемый при идентификации пользователя в системе, включающий Access и Refresh токены.

2. Admin DTO

2.1. AdminAccount - класс, используемый для получения информации об администраторе без изображения (будет применяться при редактировании информации об администраторе).

2.2. AdminAccountFull - класс, используемый для получения информации об администраторе с его изображением (применимо при просмотре страницы администратора).

2.3. AdminAccountWithPassword - класс, используемый при создании и редактировании информации об администраторе с указанием пароля.

3. Applicant DTO

3.1. Applicant Account - класс, аналогичный AdminAccount с основными полями, соответствующими классу Applicant.

3.2. Applicant AccountFull - класс, аналогичный AdminAccountFull с основными полями, соответствующими классу Applicant.

3.3. Applicant AccountWithPassword - класс, аналогичный AdminAccountWithPassword с основными полями, соответствующими классу Applicant.

4. Company DTO

4.1. Company Account - класс, аналогичный AdminAccount с основными полями, соответствующими классу Company.

4.2. Company AccountFull - класс, аналогичный AdminAccountFull с основными полями, соответствующими классу Company.

4.3. Company AccountWithPassword - класс, аналогичный AdminAccountWithPassword с основными полями, соответствующими классу Company.

5. Vacancy DTO

5.1. VacancyFull - класс, предназначенный для вывода основной информации о созданной вакансии.

5.2. VacancyVisibility - класс, предназначенный для изменения видимости созданной вакансии в системе.

5.3. VacancyWithMaster - класс, применяемый при создании вакансии с указанием основной информации и создателе системы.

5.4. VacancyWithVisibility - класс, предназначенный для вывода всей информации о вакансии с указанием ее видимости, а также информации о создателе вакансии.

6. Resume DTO

6.1. Resume Full - класс, предназначенный для вывода основной информации о созданном резюме.

6.2. Resume Visibility - класс, предназначенный для изменения видимости созданного резюме в системе.

6.3. Resume WithMaster - класс, применяемый при создании резюме с указанием основной информации о создателе системы.

6.4. Resume WithVisibility - класс, предназначенный для вывода всей информации о резюме с указанием его видимости, а также информации о создателе резюме.

7. Skill DTO

7.1. SkillFull - класс, предназначенный для вывода основной информации о созданном навыке.

7.2. SkillSimple - класс, применяемый при создании навыка с указанием основной информации.

7.3. SkillResume - класс, применяемый при создании связи между резюме и навыком.

7.4. SkillVacancy - класс, применяемый при создании связи между вакансией и навыком.

8. UserAction DTO

8.1. UserActionAdding - класс, применяемый при создании экземпляра пользовательского действия, с указанием типа и идентификатора сущности, над которой выполняется действие.

8.2. UserActionForReport - класс, предназначенный для создания отчета о деятельности или востребованности определенной сущности, созданной в системе, с указанием типа и идентификатора сущности, над которой выполняется действие.

8.3. UserActionViewing - класс, предназначенный для вывода основной информации о действии пользователя без указания типа и идентификатора сущности.

9. Report DTO

9.1. ReportFull - класс, предназначенный для вывода информации о ранее созданном в системе отчете со всей информацией.

9.2. ReportSimple - класс, применяемый при создании отчета.

10. Match DTO

10.1. MatchFull - класс, предназначенный для вывода информации о созданном сопоставлении с вакансией.

10.2. MatchSimple - класс, применяемый при создании нового сопоставления с вакансией.

10.3. MatchResume - класс, предназначенный для вывода информации о сопоставлении и основной информации о резюме, с которой сопоставляется вакансия.

Для классов из «нейросетевой» базы данных создавать Data Transfer Object не нужно, так как данные классы не будут использоваться в клиентской части приложения.

Диаграмма классов для Account DTO представлена на рисунке 2.11. Диаграммы классов для других DTO представлены на рисунках B.30_B.38 (см. прил. B).

Рисунок 2.11. Диаграмма классов Account DTO

Для осуществления связи между клиентской частью приложения и серверной применяются контроллеры, на методы которых отправляются http_запросы. Каждому классу из основной БД были разработаны контроллеры.

Уменьшения нагроможденности кода в контроллерах можно добиться, путем выноса основных вычислительных операций в сервисы (дополнительные классы). Для классов, связанных с пользовательским аккаунтом были спроектированы следующие сервисы: LoginService - сервис для идентификации пользователя в системе; TokenService - сервис, выполняющий генерацию JSON Web Token, с помощью которых будет выполняться авторизация пользователя системы, а обновление страницы клиентского приложения не приведет к необходимости дополнительной идентификации; AccountService - сервис для работы с пользовательскими аккаунтами, в том числе смены пароля, регистрации пользователей с различными ролями и их удаления; UserActionService - сервис для фиксации пользовательских действий; AdminService, ApplicantService, CompanyService - сервисы для работы с пользователями с ролями «администратор», «соискатель» и «работодатель» соответственно. Диаграмма классов для контроллера AccountContoller, связанного со всеми используемыми им сервисами представлена на рисунке 2.12. На рисунке 2.13 представлена диаграмма сервисов, выполняющий операции над пользовательскими аккаунтами.

Рисунок 2.12. Класс AccountController

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Рисунок 2.13. Сервисы, связанные с пользовательскими аккаунтами

Для классов, связанных с документами, такими как резюме или вакансия, были спроектированы следующие сервисы: VacancyService и ResumeService - сервисы, которые будут создавать вакансии и резюме соответственно; SkillService будет выполнять учет навыков в системе; ReportService и MatchService - сервисы для работы с отчетами по сопоставлениям вакансий с резюме. Отдельные сервисы были также спроектированы для таких операций как экспорт (ExportAccountService, ExportLogService, ExportResumeService, ExportSkillService, ExportVacancyService, ExportReportService), импорт (ImportVacancyService, ImportResumeService, ImportImageService) и сбор данных (CollectorService). Для классов «нейросетевой» базы данных были спроектированы два сервиса: CounterService - сервис для создания множеств на основании навыков; NeuroAnalyserService - сервис для создания, обучения, тестирования и применения нейросетей.

Дополнительными классами можно выделить перечисления: Actions - перечисление для типов действий; Entities - перечисление для типов сущностей; Roles - перечисление пользовательских ролей в системе; LayerTypes и NeuronTypes - перечисления для типов слоев и нейронов в нейросетях, соответственно; PlentyTypes - перечисление для типов множеств, SelectorTypes - перечисление для типов CSS_селекторов на сайтах-источниках данных. Диаграмма классов с перечислениями представлена на рисунке 2.14.

Рисунок 2.14. Диаграмма классов для перечислений системы

Диаграммы классов для сервисов, связанных с резюме и вакансиями, операциями экспорта, импорта, сбора и анализа данных, а также описывающие контроллеры программной системы, представлены на рисунках B.39_B.65 (см. прил. B)

2.5 Проектирование нейронной сети для системы HR Helper

Процесс сопоставления вакансии с резюме с целью определения вероятности, что кандидат подходит на предлагаемую должность [3], относится к задаче, которую можно решить с помощью использования нейронных сетей, - классификация. Результатом выполнения сопоставления должна быть вычисленная вероятность того, что кандидат с характеристиками, указанными в его резюме, подойдет на должность, описанную в вакансии.

При проектировании нейросети необходимо определить число нейронов входного и выходного слоя, а также количество скрытых слоев и число нейронов на этих слоях. При анализе вакансий и резюме можно выявить следующие основные параметры, которые должны учитываться на входном слое:

· желаемая и предлагаемая зарплата;

· имеющийся и требуемый опыт работы;

· количество имеющихся и требующихся образований;

· число изученных и требуемых языков;

· умение управлять автомобилем;

· указанные в вакансии и резюме навыки.

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

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

,

где n - число нейронов во входном слое, m - число нейронов в выходном слое, k1 - число нейронов в первом скрытом слое, k2 - число нейронов во втором скрытом слое [23].

Данная формула для предметной области сопоставления вакансий и резюме была протестирована в программе «Нейросимулятор 5», позволяющей создавать и применять нейронные сети персептронного типа [13]. Для тестирования модели были спроектированы 3 нейронные сети для 3 вакансий: аналитик, тестировщик и программист, в которых во входном слое использовались 25 нейронов, 40 и 59 соответственно. Для всех нейронных систем в проектировании применялись 2 скрытых слоя, число нейронов в которых вычислялось по формуле геометрической пирамиды. Характеристики обучаемых нейросетей представлены в таблице 2.2.

Таблица 2.2. Параметры и результаты тестирования нейросетевой модели в системе «Нейросимулятор

Характеристика нейронной сети

Аналитик

Тестировщик

Программист

Число нейронов на входном слое

25

40

59

Число скрытых слоев

2

2

2

Число нейронов на первом скрытом слое

9

12

16

Число нейронов на втором скрытом слое

3

4

4

Число нейронов на выходном слое

1

1

1

Количество итераций

7000

7000

7000

Кв. ошибка обучения

0

0

0

Кв. ошибка обобщения

0.07503

0.0689

0.07115

Максимальная ошибка

0.1215

0.1113

0.1276

Средняя квадратичная относительная ошибка (Т)(%)

2.689%

2.4845%

2.6675%

Обучение и тестирование модели выполнялось на основании данных, сгенерированных методом перебора возможных закодированных значений для каждого нейрона, отсортированных случайным образом и разделенных на обучающее, тестовое и экспериментальные множества.

На рисунке 2.15 представлен персептрон для нейронной сети, отбирающей кандидатов на должность «Программист»:

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Рисунок 2.15. Персептрон для сопоставления вакансии программиста с резюме

График обучения нейронной сети в системе «Нейросимулятор 5» представлен на рисунке 2.16.

Рисунок 2.16. График обучения нейросети для сопоставления вакансии программиста с резюме

Сравнение ожидаемых результатов сопоставления вакансий с резюме и полученных после сопоставления нейросетью представлено на рисунке 2.17.

Рисунок 2.17. Сравнение ожидаемых результатов нейросети с полученными

Результаты тестирования модели показали, что при изменении количества входных нейронов и изменении нейронов на скрытых слоях средняя относительная ошибка составила от 2.5% до 2.7%, что является достаточно высоким результатом обученности нейронной сети. При этом максимальная ошибка при тестировании нейросети составила от 0.11 до 0.13. Таким образом, можно сделать вывод, что предложенная модель нейросети, в которой при изменении количества навыков в системе число нейронов на скрытых слоях вычисляется по правилу геометрической пирамиды, является удачной и будет использоваться в разрабатываемой системе.

В результате проведенного проектирования системы HR Helper были проанализированы и выбраны технологии реализации, построена концептуальная модель предметной области в нотации диаграммы «Сущность-Связь», описано поведение системы в нотации диаграмм последовательностей UML, спроектированы основные классы системы для взаимодействия с базой данных и клиентской частью приложения, а также спроектирована и протестирована нейросетевая модель для подбора персонала на определенную вакансию.

Глава 3. Реализация системы автоматизации подбора сотрудников в IT_компаниях

Целью реализации системы HR Helper является создание информационной системы, автоматизирующей все описанные в предыдущих главах бизнес-процессы. Основными задачами реализации являются:

· описание архитектуры системы автоматизированного подбора сотрудников;

· разработка front-end компоненты системы;

· разработка back-end компоненты системы;

· разработка модуля сбора Internet-данных;

· создание нейросети и ее обучение процессу подбора сотрудников, внедрение нейросети в систему;

· тестирование и отладка готового приложения;

· подготовка документации.

3.1 Проектирование архитектуры системы HR Helper

Взаимодействие отдельных приложений, реализующих front_end и back_end компоненты одной системы, подразумевает применение клиент-серверной архитектуры приложения. Система HR Helper является примером трехзвенной архитектуры приложения, так как помимо клиентской и серверной части приложения, система включает в себя сервер баз данных.

Клиентская часть приложения _ это интерфейсная компонента системы, с которой взаимодействует конечный пользователь. Данный уровень никак не связан с базами данных, на данном уровне не выполняется сопоставление вакансий с резюме, а также не проводится сбор данных [8]. На этот уровень выносится простейшая бизнес-логика, включающая в себя проверку параметров на допустимость, простейшие операции и визуализацию данных. В концепции веб_приложения с трехзвенной архитектурой уровнем клиента является браузер, в котором отображается пользовательский интерфейс, реализованный с помощью технологии Angular в среде разработки WebStorm.

Серверная часть приложения является компонентой, реализующей слой между клиентом и базой данных [8]. На данном уровне расположена основная бизнес-логика приложения, выполняется генерация статистических отчетов, обучение, тестирование и применение нейронных сетей, сбор данных со сторонних источников, а также обработка полученных с клиента данных и прав доступа пользователя. В концепции веб_приложения с трехзвенной архитектурой уровнем сервера является приложение .Net Core, разработанное в среде разработки Visual Studio.

Сервер баз данных осуществляет хранение данных и реализуется средствами технологий систем управления базами данных, подключение к которым осуществляется только с уровня сервера приложения. В концепции веб-приложения с трехзвенной архитектурой уровнем баз данных является система, на которой развернута база данных. В случае реализуемой системы такой СУБД является PostgreSQL.

Общая схема для разрабатываемого приложения приведена на рисунке 3.1.

Рисунок 3.1. Общая схема трехзвенной архитектуры

На выбранном сервере баз данных будут развернуты две базы данных: MainDB и NeuroDB. На сервере приложений будет развернуто приложение, реализующее шаблон API .Net Core с подключенными библиотеками Counter, Exporter, Collector и Analyser. Взаимодействие между сервером баз данных и приложений будет осуществляться через SQL_запросы. На клиенте будет развернуто Angular приложение hrh_client, которое будет осуществлять взаимодействие с сервером приложений с помощью HTTP_запросов. Все части приложения будут развернуты на сервере группы IT_компаний «Simpl» c помощью набора серверов IIS. Архитектура приложения спроектирована в нотации диаграммы компонентов UML [6], представленой на рисунке 3.2.

Рисунок 3.2. Диаграмма компонентов системы HR Helper

3.2 Реализация front-end компоненты системы HR Helper

При создании front-end приложения, основанного на технологии Angular, были выявлены следующие блоки приложения: states, components, models, pages, services и utils [22].

Блок states разработан для отслеживания текущих состояний системы и их изменения:

· установка конфигурации системы при подключении файла env.json, в котором указывается, к какому серверу приложений необходимо подключаться, какую тему использовать для запущенной системы, работает ли система в тестовом режиме, находится ли система в сервисном режиме;

· отслеживание загрузки приложения;

· отслеживание загрузки страницы приложения;

· установка темы для приложения;

· установка действующего пользователя системы.

Перед созданием компонент и сервисов системы необходимо определиться со вспомогательными классами, которые будут применяться для адаптации данных, приходящих с сервера, и использоваться в связывании данных с элементами компонент, а также реализовать перечисления, тестовые наборы данных и т.д. Для этого разрабатывается блок models, в котором создаются вспомогательные классы для приложения. В подблоке entity были разработаны классы, связанные с основными сущностями системы: Account, Admin, Applicant, Company, Vacancy, Resume, Report, UserAction, Skill и Match. Пример реализации класса Company приведен ниже:

import {Account} from '@hrh/app/models/entity/account';

import {Roles} from '@hrh/app/models/role';

export class Company extends Account {

public info: string;

public inn: string;

public type: string;

public area: string;

public phone: string;

public mail: string;

public web: string;

constructor(log: string, pass: string, nam: string, inf: string, inn: string, type: string, area: string, phone: string, mail: string, pic: any = null, web: string = '') {

super(log, pass, nam, Roles.EMPLOYER, pic);

this.info = inf;

this.inn = inn;

this.type = type;

this.area = area;

this.phone = phone;

this.mail = mail;

this.web = web;

}

}

Еще одним важным блоком вспомогательных классов является блок component-models. В нем создаются классы, экземпляры которых будут использоваться для загрузки данных в разрабатываемые компоненты. Класс EntityPart будет применяться для отображения данных в компоненте Editor, PicturePart разрабатывается для компоненты PictureBox, CollectionElement - специальный класс, разрабатываемый для компонент из модуля Collection, а экземпляры класса TableElement будут применяться в компонентах модуля Table. Пример реализации класса CollectionElement приведен ниже:

export class CollectionElementButtonRule {

public title: string;

public need: boolean;

public action: () => void;

constructor(need: boolean = false, title: string = '', action: () => void = null) {

this.title = title;

this.need = need;

this.action = action;

}

}

export enum CollectionElementTypes {

ADMIN = 'admin',

APPLICANT = 'applicant',

EMPLOYER = 'company',

VACANCY = 'vacancy',

RESUME = 'resume',

REPORT = 'report',

SOURCE = 'source',

SKILL = 'skill',

MATCH = 'match'

}

export class CollectionElement {

public id: any;

public type: CollectionElementTypes;

public name: string;

public description: string;

public color: string = '';

public noData: string;

public explore: CollectionElementButtonRule = new CollectionElementButtonRule();

public master: CollectionElementButtonRule = new CollectionElementButtonRule();

public link: CollectionElementButtonRule = new CollectionElementButtonRule();

public report: CollectionElementButtonRule = new CollectionElementButtonRule();

public learn: CollectionElementButtonRule = new CollectionElementButtonRule();

public compare: CollectionElementButtonRule = new CollectionElementButtonRule();

public duplicate: CollectionElementButtonRule = new CollectionElementButtonRule();

public download: CollectionElementButtonRule = new CollectionElementButtonRule();

public visible: CollectionElementButtonRule = new CollectionElementButtonRule();

public invisible: CollectionElementButtonRule = new CollectionElementButtonRule();

public checkOn: CollectionElementButtonRule = new CollectionElementButtonRule();

public checkOff: CollectionElementButtonRule = new CollectionElementButtonRule();

public edit: CollectionElementButtonRule = new CollectionElementButtonRule();

public view: CollectionElementButtonRule = new CollectionElementButtonRule();

public remove: CollectionElementButtonRule = new CollectionElementButtonRule();

public zoomIn: CollectionElementButtonRule = new CollectionElementButtonRule();

public zoomOut: CollectionElementButtonRule = new CollectionElementButtonRule();

}

Блок test-data разработан для тестирования интерфейса системы с помощью тестовых данных. Для каждого основного класса системы был создан класс с префиксом test, который выполняет операции над тестовым набором данных, вынесенным в отдельный класс - TestData. Пример реализации класса TestResumes представлен ниже:

import {TestData} from '@hrh/app/models/test-data/test-data';

import {Utils} from '@hrh/app/utils/utils';

import {Resume} from '@hrh/app/models/entity/resume';

export class TestResumes {

private resumes: Array<Resume> = new Array<Resume>();

constructor(testData: TestData) {

const rsms = testData.resumeList;

if (rsms.length !== 0) {

rsms.forEach(rsm => {

this.resumes.push(rsm);

});

}

}

public getResumes(): Array<Resume> {

return this.resumes;

}

public getResume(id: number): Resume {

if (this.resumes.length !== 0) {

return this.resumes.find(rsm => rsm.id === id);

} else {

return null;

}

}

public addResume(id: number, pos: string, sal: number, educ: number, exp: number, lang: number, driv: boolean, vis: boolean, skills: Array<number>, link: string, master: string): void {

this.resumes.push(new Resume(id, pos, sal, educ, exp, lang, driv, vis, skills, link, master));

}

public updateResume(id: number, pos: string, sal: number, educ: number, exp: number, lang: number, driv: boolean, vis: boolean, skills: Array<number>, link: string): void {

const resume = this.getResume(id);

if (resume !== null) {

resume.position = pos;

resume.salary = sal;

resume.education = educ;

resume.experience = exp;

resume.languages = lang;

resume.driving = driv;

resume.visibility = vis;

resume.skills = Utils.pushAll([], skills);

resume.link = link;

}

}

public removeResume(id: number): void {

const resume = this.getResume(id);

if (resume !== null) {

const index = this.resumes.indexOf(resume);

if (index !== -1) {

this.resumes.splice(index, 1);

}

}

}

}

Одним из ключевых элементов веб-приложения Angualr являются компоненты - специальные классы, управляющие отображением представлений на экране. Такие классы при создании помечаются декоратором «@Component» из библиотеки «@angular/core», который идентифицирует класс как компоненту системы [20].

В разрабатываемой системе было выделено 2 основных блока с компонентами: components и pages. Первый блок является набором переиспользуемых компонент, т.е. компонент, которые будут использоваться более одного раза на нескольких страницах. Второй блок является набором более масштабных компонент, используемых для создания основных страниц.

Блок components делится на следующие подмодули:

· header-panel - компонента, которая отвечает за панель, отображающуюся вверху экрана приложения (рис. 3.3);

· editor - компонента, которая отвечает за отображение введенных данных и за ввод новых данных в систему;

· picturebox - компонента, предназначенная для отображения загруженных пользователем изображений;

· loader - компонента загрузчика, которая отображается при загрузке данных в те или иные компоненты системы;

· collection - модуль, включающий в себя несколько компонент, созданных для отображения коллекции элементов в виде списка и выполнения операций над ними;

· table - модуль, включающий в себя несколько компонент, позволяющих отображать коллекции элементов в виде таблиц.

Рисунок 3.3. Компонента HeaderPanel

Разработанная компонента Loader представляет собой загрузчик с асинхронным наблюдателем за событием загрузки [37]. С помощью декоратора «@Input» из библиотеки «@angular/core», которым отмечается определенное поле компоненты, данный класс может получать входные данные из других компонент приложения [20]. Программный код данной компоненты представлен ниже:

import { CommonModule } from '@angular/common';

import { ChangeDetectionStrategy, Component, Input, NgModule } from '@angular/core';

import { BehaviorSubject, Observable } from 'rxjs';

@Component({

selector: 'loader',

templateUrl: './loader.component.html',

styleUrls: ['./loader.component.scss'],

changeDetection: ChangeDetectionStrategy.Default

})

export class LoaderComponent {

@Input()

public text: string;

@Input()

public set complete(value: boolean) {

this._loaded.next(!value);

}

public get loaded(): Observable<boolean> {

return this._loaded.asObservable();

}

private _loaded: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);

}

Далее приведена HTML разметка компоненты:

<div *ngIf="loaded|async" class="ui active dimmer">

<div [ngClass]="{text: text}" class="ui loader">{{text}}</div>

</div>

Пример применения данной компоненты с передачей параметров text и set complete() приведены на следующем фрагменте кода:

<loader

[complete]="completed|async"

[text]="'Загрузка'"

></loader>

Компонента editor - это компонента, состоящая из элемента loader, а также стандартных HTML_тегов label, input и span. Отличительной особенностью данной компоненты является использование различных типов input в зависимости от передаваемого параметра. Тип input указывается в передаваемом экземпляре типа EntityPart. Для input были разработаны шесть основных классов - None, Password, Phone, Mail, Radio и Select. Для input типа Phone подключается дополнительный модуль «NgxMaskModule» из установленной зависимости «ngx_mask». Ниже представлен HTML_код компоненты:

<loader [complete]="completed|async" [text]="'Загрузка'"></loader>

<div class="entity-part">

<label [style.color]="labelColor">

<div>{{entity.label}}:</div>

<input *ngIf="entity.type === baseTypes.NONE" [style.width]="inputWidth" [(ngModel)]="input" placeholder='{{entity.placeholder}}' [disabled]="entity.disabled">

<input *ngIf="entity.type === baseTypes.PASSWORD" [style.width]="inputWidth" type="password" [(ngModel)]="input" placeholder='*********' [disabled]="entity.disabled">

<input *ngIf="entity.type === baseTypes.PHONE" type="text" [prefix]="'+7 '" mask="(000) 000 00-00" [showMaskTyped] = "true" [style.width]="inputWidth" [(ngModel)]="input" [disabled]="entity.disabled">

<input *ngIf="entity.type === baseTypes.MAIL" [style.width]="inputWidth" [(ngModel)]="input" placeholder='{{entity.placeholder}}' [disabled]="entity.disabled">

<div *ngIf="entity.type === baseTypes.RADIO" class="radio-button-container">

<div *ngFor="let element of entity.elements" class="radio-button" [style.width]="elementInputWidth">

<input type="radio" [(ngModel)]="element.value" [title]="element.label" id="radio{{element.id}}">

<label class="for-radio" for="radio{{element.id}}">{{element.label}}</label>

</div>

</div>

<select *ngIf="entity.type === baseTypes.SELECT" [style.width]="inputWidth" [(ngModel)]="selectedItem">

<option *ngFor="let element of entity.elements" [tabindex]="element.id" [ngValue]="element.id">{{element.label}}</option>

</select>

<span *ngIf="visibleError|async">{{entity.error}}</span>

</label>

</div>

На рисунке 3.4 представлены примеры использования компоненты Editor с типами None, Phone и Mail.

Рисунок 3.4. Компонента Editor

Компонента PictureBox - это компонента, состоящая из стандартных тегов img для отображения изображений и button класса mat-icon-button, полученного из подключенной зависимости «MatIconButton» из библиотеки «angular-materal». На рисунке 3.5. представлен пример применения компоненты без загруженного изображения.

Рисунок 3.5. Компонента PictureBox

Модуль collection состоит из 2 компонент: SimpleCollection и GroupCollection. Первая компонента предназначена для вывода списка элементов без сортировки или группировки на клиентской части приложения. Вторая компонента подразумевает отображение списка элементов, сгруппированных по передаваемым правилам. Данная компонента состоит из верхнего заглавного элемента коллекции (header_item), а также списка элементов. На уровне интерфейса реализован скроллинг (движение информации по вертикали) элементов внутри контейнера. Пример использования SimpleCollection представлен на рисунке 3.6.

Рисунок 3.6. Компонента SimpleCollection

Пример использования компоненты GroupCollection в рамках «Опубликованных вакансий», сгруппированных по опубликовавшим их копаниям представлен на рисунке 3.7.

Рисунок 3.7. Компонента GroupCollection

Модуль table состоит также из двух компонент: SkillTable и ActionTable.

Первая компонента таблиц создана для добавления и учета навыков в системе, вторая компонента - для отображения пользовательских действий в системе с возможностью фильтрации по полям.

Компоненты представляют собой таблицы с заголовочным элементом сверху и текстовыми полями над таблицей. Элементы таблицы также поддерживают скроллинг. Примеры компонент SkillTable и ActionTable представлены на рисунках 3.8 и 3.9 соответственно.

Рисунок 3.8. Компонента SkillTable

Рисунок 3.9. Компонента ActionTable

Следующий блок - services, предназначен для работы с данными в системе, является связующим элементом между частями back-end и front-end. В данном блоке отправляются все HTTP-запросы на сервер, принимаются и обрабатываются. Выполнение HTTP-запросов реализовано через технологию Promise - один из основных способов организации асинхронного кода в JavaScript [11, 37]. HTTP_запрос складывается в цепочку последовательно выполняющихся Promise, результат которых преобразуется и отображается на странице.

В целях уменьшения количества используемого кода был создан базовый сервис «HrhApiService», в котором для каждого типа HTTP_запроса был создан метод, который будет применяться в наследуемых сервисах. Ниже приведен пример использования запроса типа «HttpGet»:

public refreshToken() {

return this.post(`${this.accountUrl}/refresh`, {

token: window.sessionStorage.getItem('refresh')

},

{

'Content-Type': 'application/json',

}, false);

}

public updateWindowSession(response: any, headers?: any): any {

window.sessionStorage.setItem('access', response.accessToken);

window.sessionStorage.setItem('refresh', response.refreshToken);

if (Utils.exists(headers) && Utils.exists(headers['Authorization'])) {

headers['Authorization'] = 'Bearer ' + window.sessionStorage.getItem('access');

} else {

headers = {};

}

return headers;

}

public get(url: string, headers?: any, needToCheck = true, jsonConvert = true, first = true) {

if (Utils.missing(headers)) {

headers = {

'Content-Type': 'application/json'

};

}

return fetch(url, {

method: 'GET',

headers: headers,

}).then((response) => {

if (Utils.exists(response.ok) && response.ok) {

if (jsonConvert) {

return response.json();

} else {

return response;

}

} else {

if (needToCheck && first) {

return this.refreshToken()

.then((response) => {

if (Utils.exists(response.accessToken)) {

headers = this.updateWindowSession(response, headers);

}

return this.get(url, headers, needToCheck, jsonConvert, false);

});

} else {

return response;

}

}

});

}

Алгоритм get-запроса с проверкой действующего токена и повторной авторизацией через refresh-токен представлен на рисунке 3.10.

Рисунок 3.10. Диаграмма активностей, описывающая процесс выполнения Get-запроса

Пример применения наследуемых от HrhApiService методов get, delete и post в сервисе HrhUserActionService:

export class HrhUserActionsService extends HrhApiService {

private actionUrl = `${this.config.WebApiUrl}/userAction`;

constructor(protected http: HttpClient,

@Inject(AppStateToken) protected appState: IAppState,

@Inject(AppConfigToken) protected config: IAppConfig

) {

super(http, appState, config);

}

public getActions() {

return this.get(this.actionUrl, {

'Authorization': 'Bearer ' + window.sessionStorage.getItem('access'),

'Content-Type': 'application/json'

});

}

public addAction(u: string, p: string, actionT: ActionType, pars: string = '-', entityT: EntityTypes = EntityTypes.EMPTY, entityId: string = '', succ: boolean = true) {

return this.post(this.actionUrl, {

user: u,

page: p,

actionType: actionT,

success: succ,

params: pars,

entityType: entityT,

entityIdentificator: entityId

}, {

'Authorization': 'Bearer ' + window.sessionStorage.getItem('access'),

'Content-Type': 'application/json'

});

}

public deleteAction(id: number) {

return this.delete(`${this.actionUrl}/${id.toString()}`, {

'Authorization': 'Bearer ' + window.sessionStorage.getItem('access'),

'Content-Type': 'application/json'

});

}

Также был создан дополнительный сервис HrhTestDataService, который использует тестовый набор данных в приложении.

Блок pages представляет собой набор страниц, доступных пользователям для работы. Angular поддерживает удобную маршрутизацию по приложению с дополнительным ограничительным классом, наследуемым от класса CanActivate из библиотеки «angular-router». Для такой проверки создаются классы AppGuard и MainGuard. Первый класс проверяет при заходе на страницу, имеет ли пользователь текущую рабочую сессию в приложении (через состояние страницы), а второй переотправляет на страницу «Redirected», если система находится в сервисном режиме.

Маршрутизация задается в модулях для каждой компоненты, как это показано на примере модуля для компоненты MainComponent:

...

Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.