Вы находитесь на странице: 1из 76

Федеральное государственное образовательное бюджетное учреждение

высшего образования
«Финансовый университет при Правительстве
Российской Федерации»
(Финансовый университет)
Колледж информатики и программирования
(наименование структурного подразделения)

Выпускная квалификационная работа

Тема «Разработка конструктора квестов для студентов колледжа»


(наименование)
Студент Копорев Михаил Андреевич
(фамилия, имя, отчество полностью)
Учебная группа 4ПКС-219

Специальность 09.02.03 Программирование в компьютерных системах


(код и наименование специальности)

Руководитель выпускной
квалификационной работы М.В. Морозова
(подпись) (инициалы, фамилия)

Консультант выпускной
квалификационной работы
(при наличии) (подпись) (инициалы, фамилия)

Председатель предметной
(цикловой) комиссии Т.Г. Аксёнова
(подпись) (инициалы, фамилия)

Москва – 2023 г.
СОДЕРЖАНИЕ
ВВЕДЕНИЕ..................................................................................................................3
ГЛАВА 1 ПРЕДПРОЕКТНОЕ ИССЛЕДОВАНИЕ..................................................7
1.1 Описание предметной области.........................................................................7
1.2 Сравнительный анализ существующих программ.........................................8
1.3 Постановка задачи разработки конструктора квестов.................................10
1.4 Характеристика инструментальных средств разработки.............................12
ГЛАВА 2 ПРОЕКТИРОВАНИЕ И РЕАЛИЗАЦИЯ ПРОГРАММЫ....................16
2.1 Разработка спецификаций и проектирование конструктора квестов.........16
2.2 Реализация Web API........................................................................................20
2.3 Реализация десктопного приложения............................................................29
2.4 Реализация мобильного приложения.............................................................41
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ................................................57
ПРИЛОЖЕНИЕ.........................................................................................................60

2
ВВЕДЕНИЕ
В современную цифровую эпоху информационные технологии произвели
революцию в том, как мы общаемся, учимся и взаимодействуем с окружающим
миром. С появлением передовых технологий традиционные методы обучения и
оценивания претерпели значительные изменения. Одной из конкретных
областей, которая приобрела огромную популярность и эффективность,
является разработка интерактивных квестов, которые увлекают учащихся и
бросают им вызов в захватывающей манере.
Появление мобильных устройств оказало глубокое влияние на нашу
повседневную жизнь. Эти устройства больше не являются просто
инструментами общения, они стали незаменимыми для многих аспектов нашей
личной и профессиональной жизни. Начиная с доступа к социальным сетям и
заканчивая онлайн-покупками, мобильные телефоны все чаще становятся
основным способом взаимодействия людей с цифровым миром.
Стремительное развитие ИТ-технологий позволяют создавать новые
инновационные приложения и сервисы. Использование API (Application
Programming Interface) упрощает подключение различных систем и устройств,
сделав возможным создание сложных приложений. Развитие средств
разработки программного обеспечения и API-интерфейсов дает возможность
создавать приложения, которые удобны в использовании. Разработка API-
интерфейсов позволяет взаимодействовать мобильной и десктопной версии
приложения, что позволяет легко создавать и выполнять различные задачи.
Возросшая в последнее время тенденция использования QR-кодов (Quick
Response code) открыло перед разработчиками новые возможности для
создания интерактивных квестов.
Как и описывалось выше, QR-коды стали повсеместными в современном
мире, обеспечивая быстрый и простой способ доступа к информации с
помощью простого сканирования. Они используются в широком спектре
приложений, от рекламных и маркетинговых кампаний до систем продажи
билетов и управления запасами. Также недавним примером использования QR-
3
кодов являются сертификаты с данными о прививке от коронавируса.
Возможность хранить большие объемы данных в небольшом пространстве, и
простота сканирования делают QR-коды идеальным инструментом для
создания интерактивных квестов. Использование QR-кодов в интерактивных
квестах позволяет участникам быстро получать доступ к задачам, а также
быструю обратную связь о процессе выполнения заданий. Они могут
отсканировать код и получить задание на свое мобильное устройство, что
частично избавляет от необходимости бумажной волокиты. Преподаватели,
тренеры и разработчики игр используют эту технологию для привлечения
студентов и пользователей. Процесс обычно включает в себя создание серии
задач или заданий, которые участники должны выполнить. Эти задачи могут
быть в форме вопросов, головоломок или физических заданий.
Интерактивные квесты обеспечивают увлекательный и захватывающий
способ изучения новых концепций. Представляя задания в увлекательной и
интерактивной форме, квесты могут помочь стимулировать творческий
потенциал и развить навыки решения проблем. Интерактивные квесты можно
использовать для обучения новым навыкам, закрепления знаний и поощрения
командной работы. Они особенно полезны в образовательных учреждениях, где
их можно использовать для создания увлекательного и интерактивного
процесса обучения. API предоставляет учителям платформу для создания
заданий, которые могут быть выполнены с помощью мобильного устройства.
Создание мобильного и десктопного приложения для создания
интерактивных квестов с использованием QR-кодов и связанного с ним API,
который обеспечивает передачу данных между мобильной и десктопной
версиями приложения, представляет собой захватывающую новую разработку.
Целью этой работы является создание конструктора квестов для
студентов колледжа. Данная выпускная квалификационная работа является
групповой. Конструктор квестов будет создан командой из трех человек.
Первый участник (Кенден Ангелина) будет разрабатывать мобильную версию
приложения для студентов. Второй участник (Копорев Михаил) будет
4
заниматься созданием версии приложения на компьютеры для преподавателей.
Третий участник (Казак Юрий) будет создавать Web API для предоставления
данных приложениям.
Для достижения этой цели шаг за шагом, нужно выполнить следующие
задачи: проектирование и создание базы данных, разработка Web API,
разработка десктопного приложения, разработка мобильного приложения,
тестирование и отладка программ, составление пояснительной записки.
Объект исследования: конструктор квестов для студентов колледжа.
Предмет исследования: среда и библиотеки для конструктора квестов для
студентов колледжа.
Для предпроектного исследования будут применены следующие методы:
анализ предметной области, сравнение существующих решений и
моделирование нового решения, а также анализ и сравнение сред для
разработки и возможных методов.
Источниковой базой исследования являются электронные ресурсы с
описанием среды, языка и библиотеки для разработки, для формирования
пояснительной записки были использованы утвержденные ГОСТ’ы и учебники.
При разработке будут использованы следующие средства разработки и
языки программирования:
- фреймворк «Swagger»;
- средство для построения диаграмм «Draw.io»;
- средство формирования «установщика» «Actual Installer»;
- средство для формирования задач «MS To Do»;
- средство для формирования пояснительной записки «MS Word»;
- средство для формирования презентации «MS PowerPoint».
При разработке Web API будут использованы следующие средства
разработки и языки программирования:
- утилита для API «Postman»;
- фреймворк «ASP.NET»;
- язык программирования «C#»;
5
- средство управления базой данных «MySQL»;
- среда разработки «JetBrains Rider»;
- среда разработки «JetBrains DataGrip».
При разработке десктопного приложения будут использованы следующие
средства разработки и языки программирования:
- язык программирования «C#»;
- среда разработки «Visual Studio»;
- графическая библиотека «WPF UI».
При разработке мобильного приложения будут использованы следующие
средства разработки и языки программирования:
- фреймворк «Flutter»;
- язык программирования «Dart»;
- среда разработки «Android Studio».
Таким образом будет разработан комплекс программ для конструктора
квестов для студентов колледжа.

6
ГЛАВА 1 ПРЕДПРОЕКТНОЕ ИССЛЕДОВАНИЕ
1.1 Описание предметной области
Темой выпускной квалификационной работы является разработка
конструктора квестов для студентов колледжа.
Интерактивные квесты можно описать как динамичный процесс
обучения, который вовлекает учащихся с помощью сочетания задач,
головоломок и поручений. Эти квесты часто включают сюжетную линию или
тему, которая ведет участников через серию взаимосвязанных действий. Они
поощряют активное участие, критическое мышление, решение проблем,
сотрудничество и исследования. Интерактивный квест обычно состоит из
нескольких этапов или уровней, каждый из которых представляет уникальные
задачи и возможности для обучения. Эти испытания могут принимать
различные формы, такие как викторины, головоломки, ребусы-загадки, охота за
сокровищами или сценарии ролевых игр. Участники продвигаются по квесту,
успешно выполняя задания, приобретая знания и открывая новые этапы. Чтобы
продвинуться в выполнении задания, студенты должны продемонстрировать
свое понимание предмета, представив правильные ответы или выполнив
конкретные задания. Попутно они получают обратную связь, подсказки и
руководство, которые помогут им в обучении.
QR-коды, сокращенно от кодов быстрого реагирования, представляют
собой двумерные штрих-коды, которые можно отсканировать с помощью
смартфона или приложения для считывания QR-кодов. Они состоят из узора из
черных квадратов на белом фоне, и каждый код содержит закодированную
информацию, такую как текст, URL-адреса или другие данные. QR-коды
приобретают все большее значение в различных областях, включая
образование. Они служат мостом между физическим и цифровым мирами,
обеспечивая беспрепятственный доступ к онлайн-ресурсам, информации и
интерактивному взаимодействию. В контексте интерактивных квестов QR-коды
используются для привязки физических объектов, местоположений или

7
подсказок к цифровому контенту и задачам. Включив QR-коды в
интерактивные задания, учащиеся могут просто сканировать коды с помощью
своих смартфонов, чтобы получить доступ к информации, связанной с
заданием, отправить ответы или перейти к следующему этапу. QR-коды
обеспечивают удобное и эффективное средство подключения автономного и
онлайн-компонентов квеста, устраняя необходимость в ручном вводе данных
или обширной бумажной волоките. Мы стремимся использовать их
возможности для улучшения процесса создания квестов и содействия
беспрепятственному взаимодействию между физической и цифровой учебными
средами.
1.2 Сравнительный анализ существующих программ
Для сравнения с будущим конструктором квестов были взяты два
продукта: «Квестодел» и «Surprise Me».
На сайте «Квестодел» на рисунках 1–2 можно сгенерировать или
придумать самим задания для квеста. Имеется каталог из множества видов
заданий: шифры, коды, координаты, ребусы и так далее. Есть возможность
оставлять подсказки к следующему заданию для линейности квеста. После
генерации заданий их можно распечатать или сохранить в файл. Сайт имеет
устаревший интерфейс, который вряд ли привлекает молодую аудиторию. Из-за
обилия видов заданий некоторые из них невозможно выполнить без
инструкций, например задания с шифрами Виженера или Цезаря. Весь
доступный функционал полностью бесплатный.

8
Рисунок 1. Сайт «Квестодел»

Рисунок 2. Генерация заданий на сайте «Квестодел»


«Surprise Me» – онлайн-конструктор для квестов. Для начала надо создать
квест в онлайн-конструкторе на рисунке 3–4. Затем прислать участникам квеста
ссылки доступа. И после этого доступна онлайн статистика по прохождению
квеста. Квесты можно проходить через браузер с компьютера или телефона. А
также в их собственном приложении. Доступно разнообразие видов заданий:
текст, фото, видео, аудио и так далее. У сайта и приложения приятный и
современный интерфейс, присутствует пошаговый гайд при создании квеста.
Весь функционал доступен только при создании квеста до 5 участников. За
увеличение количества участников предусмотрена плата.

Рисунок 3. Сайт «Surprise Me»

9
Рисунок 4. Конструктор «Surprise Me»
Благодаря анализу двух аналогичных продуктов конструктора квестов,
мы создадим свой конструктор, учитывая вышеописанные достоинства и
недостатки.
1.3 Постановка задачи разработки конструктора квестов
Приложение будет иметь две версии: на персональный компьютер для
преподавателей и на мобильный телефон для студентов. А также мы
разработаем веб-сервер для доступа к данным из базы данных.
Web API будет нацелено не на конечного пользователя, а на
программистов, которые будут использовать его для написания мобильного и
десктопного приложения. API будет предоставлять программисту возможность
регистрации и входа пользователя, а также аутентификацию через JWT токен.
Работа десктопной программы будет осуществляться путем ввода
информации пользователем, при помощи мыши и клавиатуры. Для навигации
будет предусмотрена боковая панель с кнопками перехода по страницам
приложения. Ввод информации будет сделан посредством нажатия на кнопки,
выбора данных из списка и ввода текста в соответствующие контейнеры.
В десктопном приложении будет реализована система регистрации и
авторизации. При первичной регистрации пользователю не будет выдаваться
роль, подтверждать регистрацию должны будут администраторы.
Для преподавателей будут доступны 3 функциональных окна
приложения: окно создания квестов, в котором пользователи могут
10
взаимодействовать со своими заданиями, окно назначения квестов, в котором
преподаватели смогут прикреплять созданные квесты к студентам и окно для
просмотра данных студентов.
Администраторам, в отличие от преподавателей, будет доступна
информация обо всех пользователях и о полном списке заданий. Также у них
будет два дополнительных окна: одно с функциями регистрации новых
пользователей и изменения данных уже существующих, а второе со списком
пользователей, ждущих подтверждения.
Минимальные системные требования:
- операционная система: Windows 10;
- оперативная память: 4 ГБ;
- процессор: Intel Pentium IV 2.8 GHz;
- видеокарта: Intel HD 4000.
Мобильное и десктопное приложение будут общаться в Web API через
CRUD (Create, Read, Update, Delete) запросы. Через которые можно будет
добавлять, получать, изменять и удалять объекты из базы данных.
Мобильное приложение для Android и iOS будет иметь авторизацию для
пользователей. Регистрация же будет осуществляться через десктоп
приложение. Всего в мобильном приложении, так же, как и в десктопном, три
роли пользователей: администратор, преподаватель, студент. Приложение
будет ориентировано в основном на студентов, которые будут ходить по
помещению с телефонами и сканировать QR-код, но тут также есть отдельные
роли для преподавателя и админа для различных форс-мажорных ситуаций.
Во вкладке заданий администратор может просмотреть все созданные
вопросы, посмотреть правильный ответ. Также тут будет работать поиск по
квестам, как и у всех пользователей. В разделе пользователей администратор
будет видеть всех пользователей, будет добавлена возможность менять им
имена и роли. Сканер QR-кода будет показывать задание и кем оно создано.

11
Преподаватель также будет иметь возможность просмотреть задания, но
только те, которые создал он сам. В списке пользователей будет просмотр
только студентов. Функционал сканера будет такой же, как и у администратора.
Студент будет просматривать и выполнять только задания, адресованные
ему. Новые задания он будет добавлять через сканер с помощью QR-кода. При
выполнении квеста будет видно, правилен ли ответ или нет. Если ответ
неверен, приложение подскажет правильный вариант после отправки
преподавателю, но возможность менять свой ответ будет отсутствовать.
Минимальные требования для мобильного приложения:
- операционная система: Android или iOS;
- версия Андроид 11.0 и выше;
- версия iOS 14.0 и выше;
- оперативная память не менее 2Гб;
- место на хранилище не менее 300Мб;
- доступ к камере;
- доступ к интернету.
1.4 Характеристика инструментальных средств разработки
«Swagger» – это мощный, но простой в использовании набор
инструментов разработки API для групп и отдельных лиц, обеспечивающий
разработку на протяжении всего жизненного цикла API, от проектирования и
документации до тестирования и развертывания. [19.]
«MySQL» – это система управления базами данных. MySQL позволяет
создавать высокопроизводительные и масштабируемые приложения
оперативной обработки транзакций (OLTP). Он обеспечивает простоту
использования, которая сделала MySQL известным, наряду с промышленной
производительностью и надежностью. MySQL включает InnoDB, что делает его
полностью интегрированной базой данных, безопасной для транзакций и
совместимой с ACID. Кроме того, MySQL Replication позволяет создавать
высокопроизводительные и масштабируемые приложения.

12
«JetBrains DataGrip» – это многоядерная среда базы данных. Если в СУБД
есть JDBC-драйвер, к нему можно подключиться через DataGrip. Он
обеспечивает самоанализ базы данных и различные инструменты для создания
и изменения объектов для поддерживаемых движков. [25.]
Десктопное приложение и Web API будут разрабатываться на языке
программирования C#. Это современный объектно-ориентированный и
типобезопасный язык программирования. C# позволяет разработчикам
создавать разные типы безопасных и надежных приложений, выполняющихся в
.NET. Он объектно-ориентированный, ориентированный на компоненты язык
программирования. C# предоставляет языковые конструкции для
непосредственной поддержки такой концепции работы. Благодаря этому C#
подходит для создания и применения программных компонентов. С момента
создания язык C# обогатился функциями для поддержки новых рабочих
нагрузок и современными рекомендациями по разработке ПО. [16.]
При разработке на C# будет использована среда «Microsoft Visual Studio».
Интегрированная среда разработки Visual Studio – это стартовая площадка для
написания, отладки и сборки кода, а также последующей публикации
приложений. Помимо стандартного редактора и отладчика, которые есть в
большинстве сред IDE, Visual Studio включает в себя компиляторы, средства
автозавершения кода, графические конструкторы и многие другие функции для
улучшения процесса разработки. [22.]
Для разработки интерфейса десктопного приложения будет
использоваться «WPF UI». WPF UI – это библиотека, предназначенная для
создания современных пользовательских интерфейсов в среде Windows
Presentation Foundation (WPF). По умолчанию библиотека создана для .NET 6.
[15.]
Для создания Web API будет использоваться «ASP.NET» (Active Server
Pages для .NET) – платформа разработки веб-приложений, в состав которой
входят: веб-сервисы, программная инфраструктура, модель программирования,

13
от компании Майкрософт. ASP.NET входит в состав платформы .NET
Framework и является развитием более старой технологии Microsoft ASP.
В качестве среды разработки Web API будет использовано «JetBrains
Rider» для работы с ASP.NET. Rider – кроссплатформенная интегрированная
среда разработки программного обеспечения для платформы .NET,
разрабатываемая компанией JetBrains. Поддерживаются языки
программирования C#, VB.NET и F#. В его основе лежит другой продукт
JetBrains – ReSharper. Среда поддерживает платформы .NET Framework, .NET и
Mono. Работает на операционных системах Windows, macOS, Linux.
«Postman» – это API платформа для создания и использования API
интерфейсов. Postman упрощает каждый этап жизненного цикла API и
оптимизирует совместную работу.
Средой разработки для мобильного приложения будет «Android Studio».
Android Studio – это официальная среда разработки для Android, которая
включает в себя все необходимое для создания приложений для Android и iOS.
[24.]
Также для мобильной разработки будет использован фреймворк «Flutter».
Flutter – это фреймворк с открытым исходным кодом для создания красивых,
скомпилированных в собственном коде мультиплатформенных приложений из
единой кодовой базы. [26.]
«Dart» – это оптимизированный для клиента язык программирования для
разработки быстрых приложений на любой платформе. Его цель – предложить
наиболее продуктивный язык программирования для многоплатформенной
разработки в сочетании с гибкой платформой выполнения для фреймворков
приложений. Dart также является основой Flutter. Dart предоставляет язык и
среду выполнения для приложений Flutter, но Dart также поддерживает многие
основные задачи разработчиков, такие как форматирование, анализ и
тестирование кода. [23.]
Для создания различных диаграмм для будущей разработки будет
использоваться сайт «Diagrams.net» (Draw.io). Это бесплатное онлайн-
14
программное обеспечение для построения диаграмм. Вы можете использовать
его как средство создания блок-схем, программное обеспечение для построения
сетевых диаграмм, для создания UML в режиме онлайн, как инструмент для
создания диаграмм ER, для разработки схемы базы данных, для создания
BPMN в режиме онлайн, как создатель схем и многое другое. [18.]
Для дальнейшего удобства установки уже готовой программы будет
использоваться инсталлятор «Actual Installer». Actual Installer – это
профессиональный инсталлятор, который позволяет создавать качественные
установочные программы с невероятной легкостью. Интуитивно-понятный
интерфейс программы позволит забыть о сложностях скриптовых языков и
создавать полноценные установочные пакеты, готовые для дистрибуции, всего
за несколько минут.
«Microsoft To Do» – приложение для управления задачами, способное
работать на разных платформах, обеспечивает доступ к списку задач.
При разработке документации к проекту будут использоваться
следующие программы: «Microsoft Word» и «Microsoft PowerPoint». [20.]
«Microsoft Word» – текстовый процессор, предназначенный для создания,
просмотра, редактирования и форматирования текстов статей, деловых бумаг, а
также иных документов, с локальным применением простейших форм
таблично-матричных алгоритмов. Выпускается корпорацией Microsoft в составе
пакета Microsoft Office.
«Microsoft PowerPoint» – программа подготовки презентаций и просмотра
презентаций, являющаяся частью Microsoft Office. Материалы, подготовленные
с помощью PowerPoint, предназначены для отображения на большом экране –
через проектор, либо телевизионный экран большого размера.

15
ГЛАВА 2 ПРОЕКТИРОВАНИЕ И РЕАЛИЗАЦИЯ ПРОГРАММЫ
2.1 Разработка спецификаций и проектирование конструктора квестов
На рисунке 5 представлена диаграмма вариантов использования для
десктопного приложения.

Рисунок 5. Диаграмма вариантов использования для десктопного


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

Рисунок 6. Диаграмма вариантов использования мобильного приложения


16
На рисунке 7 представлена структурная схема десктопного приложения.

Рисунок 7. Структурная схема десктопного приложения


На рисунке 8 представлена структурная схема мобильного приложения.

Рисунок 8. Структурная схема мобильного приложения


На рисунке 9 представлена функциональная схема преподавателя.

17
Рисунок 9. Функциональная схема преподавателя
На рисунке 10 представлена функциональная схема студента.

Рисунок 10. Функциональная схема студента


На рисунке 11 изображена ER-диаграмма базы данных. Словарь данных в
приложении А.
18
Рисунок 11. ER-диаграмма базы данных
Для формирования базы данных с заданной структурой, первоначально
была выбрана подходящая система управления базами данных (СУБД). Затем
была разработана основная структура базы данных, которая включала три
основные таблицы: «Пользователи», «Задания» и «Назначенные задания».
Первой таблицей «Пользователи» была определена структура,
включающая следующие столбцы: «Имя», «Фамилия», «Отчество», «Логин»,
«Пароль» и «Роль». Эти поля позволяют хранить информацию о пользователях,
включая их персональные данные, учетные записи для входа и их роли в
системе.
Далее была создана таблица «Задания». Однако, в процессе разработки
была выявлена проблема с масштабируемостью заданий, особенно в случае,
когда различные типы заданий требовали использования разных таблиц. Это
привело к необходимости создания большого количества таблиц и
19
потенциально огромной базы данных. Однако, с помощью хранения данных
заданий в виде JSON (JavaScript Object Notation), в таблице «Задания», удалось
упростить структуру базы данных и обеспечить легкую масштабируемость. Это
позволило добавлять новые типы заданий, используя одну и ту же таблицу,
избегая необходимости создания отдельных таблиц для каждого типа задания.
Таким образом, база данных стала более гибкой и способной эффективно
обрабатывать разнообразные типы заданий. Также в таблице были определены
столбцы для идентификатора пользователя, который создал задание, и краткого
названия задания. Это позволяет связать задания с конкретными
пользователями и хранить дополнительные сведения о них.
Наконец, была создана таблица «Назначенные задания». В этой таблице
содержатся столбцы: для идентификатора пользователя, которому было
назначено задание, идентификатора задания, флага, указывающего выполнено
ли задание, а также временных меток, обозначающих время выдачи и
завершения задания. Это позволяет отслеживать прогресс выполнения заданий,
а также управлять назначением и сроками их выполнения.
После определения структуры таблиц были созданы скрипты для
создания самих таблиц, а также необходимые индексы и ограничения для
обеспечения целостности данных. Кроме того, были разработаны запросы и
процедуры для управления данными в базе данных, включая добавление,
обновление и удаление записей, а также выполнение различных видов запросов
для извлечения информации из базы данных.
2.2 Реализация Web API
В целях экономии ресурсов было принято решение поставить сервер на
локальную машину и открыть к ней глобальный доступ. Однако сервер не
функционирует круглосуточно. Web API нацелена на разработчика, который
будет делать свое приложение используя данные из API. Поэтому, нужно было
разработать документацию, которая будет помогать разработчику понимать,
что именно требуется для выполнения определенного запроса. На рисунке 12

20
показан интерфейс «swagger», который демонстрирует все запросы, которые
может обработать сервер.

Рисунок 12. Интерфейс онлайн документации


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

Рисунок 13. Запрос с регистрации пользователя

21
Для удобства пользования онлайн документации, можно также
выполнить этот запрос прямо на сайте нажав кнопку «Try it out», а потом
«Execute», предварительно наполнив запрос нужными данными. На рисунке 14
показано, что после нажатия кнопки «Try it out», пользователю нужно будет
заполнить данные, которые требует запрос и нажать «Execute».

Рисунок 14. Начало выполнения запроса


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

22
Рисунок 15. Вывод выполненного запроса
Запрос на регистрацию возвращает только статус код запроса. На рисунке
15, код запроса равен 200, это означает, что запрос выполнился без ошибок.
Если код запроса будет отличаться, это может означать, что произошла ошибка
во время обработки запроса, например, ошибка 500 которая возникает, когда на
стороне сервера возникли непредвиденные затруднения. Они никак не зависят
от действий пользователя. Однако есть ошибка с кодом 404, это означает что
искомый запрос был не найден.
Рисунок 16 демонстрирует «login» запрос, который на вход требует
данные для аутентификации, а на выходе дает уникальный токен, который
требуется для идентификации пользователя.

Рисунок 16. Запрос на вход


При успешном выполнении запроса на рисунке 17, который должен
вернуть какие-либо данные, возвращается JSON представление, которое будет
обрабатывать программист при написании приложения.

23
Рисунок 17. Успешное выполнение запроса
Большинство запросов возвращают данные, которые не должны быть
доступны посторонним пользователям. Например, студент не может получить
список всех пользователей, в то время как администратор имеет на это право.
Для этого используются специальные токены, которые нужно отправлять
вместе с запросом для идентификации пользователя. Далее на сервере этот
токен обрабатывается и сервер понимает, какой пользователь и с какими
правами требует данные. На рисунке 18 показан запрос, который требует токен
для успешного выполнения. Для того чтобы пользователю было понятно, что
этот запрос требует токен, у этого запроса появляется иконка замка.

Рисунок 18. Запрос требующий токен

24
Если не предоставить токен, то запрос вернет ошибку 401, а если токен
предоставлен, но владелец этого токена не имеет прав, то запрос вернет ошибку
403.
Для того чтобы обеспечить должную безопасность для приложения, так
как токены не вечны, через определенное количество времени токен нужно
обновлять. В данном случае токен существует 15 минут. Чтобы пользователю
не нужно было каждые 15 минут входить заново в приложение, был реализован
токен обновления который выдается вместе с обычным токеном во время входа
в приложение и хранится у пользователя. У него время жизни намного дольше,
чем у обычного токена и он служит лишь для того, чтобы обновить основной
токен. Для этого был реализован отдельный запрос на рисунке 19.

Рисунок 19. Запрос на обновление токена


Запрос с рисунка 19 автоматически берет токен обновления из «cookie» и
сверяет его с хранящимся в базе токеном и если они совпадают, то генерирует
новый токен доступа и возвращает его.
Рисунок 20 демонстрирует успешное выполнение запроса при
предоставлении специального токена. Однако если токен не будет
предоставлен, запрос вернет ошибку 401, что и показано на рисунке 21.

25
Рисунок 20. Успешное выполнение запроса

Рисунок 21. Ошибка во время выполнения запроса


В листинге 1 показан код запроса с рисунка 18. На нем можно увидеть,
что доступ к этому запросу имеют только пользователи с ролью «admin» и
«teacher». Также доступна фильтрация по роли.
Листинг 1. Код запроса на получение всех пользователей
26
[HttpGet("all")]
[Authorize(Roles = $"{nameof(UserRole.Admin)},{nameof(UserRole.Teacher)}")]
public async Task<IActionResult> GetAll(string? role = null)
{
var users = await _userService.GetUsers();
List<UserResponse> userResponses;

if (role is not null)


{
userResponses = users
.Where(user => user.UserRole.ToString() == role)
.Select(UserMapper.MapUser)
.ToList();
}
else
{
userResponses = users
.Select(UserMapper.MapUser)
.ToList();
}

return Ok(userResponses);
}

Для комфортного доступа к базе данных были написаны отдельные


сервисы для работы с пользователями и заданиями. В листинге 2 показан
интерфейс сервиса с пользователями, и в листинге 3 интерфейс для заданий.
Листинг 2. Интерфейс сервиса с пользователями
public interface IUserService
{
#region CRUD (Create, Read, Update, Delete)

public Task<ErrorOr<User>> Create(CreateUserDTO createUserDto);


public Task<ErrorOr<User>> GetUser(int id);
public Task<ErrorOr<User>> Update(int id, PatchUserDTO patch);
public Task<ErrorOr<bool>> Delete(int id);
#endregion
public Task<List<User>> GetUsers();
public Task<ErrorOr<User>> GetUserByUsername(string username);
public Task<ErrorOr<User>> GetUserByRefreshToken(string refreshToken);
public Task<ErrorOr<User>> SetUserRole(User user, UserRole userRole);
public Task<ErrorOr<User>> GetLoggedUser();
}

Листинг 3. Интерфейс сервиса с заданиями


27
public interface IQuestService
{
#region CRUD (Create, Read, Update, Delete)

public Task<ErrorOr<Quest>> Create(CreateQuestDTO request);


public Task<ErrorOr<Quest>> Get(int id);
public Task<ErrorOr<Quest>> Update(int id, QuestPatchDTO patch);
public Task<ErrorOr<bool>> Delete(int questId);

#endregion
public Task<ErrorOr<List<Quest>>> GetQuests();
public Task<ErrorOr<Quest>> GetByLabel(string label);
public Task<ErrorOr<List<User>>> GetUnassigned(int id);
public Task<ErrorOr<User>> AddQuestToUser(int userID, int questID);
public Task<ErrorOr<User>> DeleteQuestFromUser(int userID, int
questID);
public Task<ErrorOr<UserQuest>> Complete(Quest quest, bool isCorrect);
public Task<ErrorOr<UserQuest>> CompleteUserQuest(User user, Quest
quest, bool isCorrect);
}

Во время тестирования не было обнаружено ошибок. Если пользователь


отправит API неправильные данные, то получит код ошибки и ее описание на
рисунке 22.

Рисунок 22. Ошибка при выполнении запроса

28
Чтобы использовать Web API для тестирования и написания приложения,
нужно скачать проект с репозитория и запустить его. Во время запуска
откроется документация в браузере по умолчанию и можно приступать к
работе.
2.3 Реализация десктопного приложения
При первичном запуске приложения открывается окно входа под учетной
записью на рисунке 23.
Данные для входа:
- администратор: логин «Yurami», пароль «123»;
- преподаватель: логин «tga», пароль «123»;
- студент: логин «dasha», пароль «123».

Рисунок 23. Окно входа


Передача информации осуществляется при помощи паттерна разработки
MVVM(Model-View-ViewModel). В листинге 4 показана привязка данных к
текстовому полю в файле .xaml. Пример объявления переменной, содержащей
данные для привязки, представлен в листинге 5.
Листинг 4. Привязка данных
<ui:TextBox MinWidth="150"

Text="{Binding ViewModel.Login}"

29
PlaceholderText="Username"/>

Листинг 5. Объявление переменной


[ObservableProperty]
[NotifyCanExecuteChangedFor("LogInClickCommand")]
private string _login = string.Empty;

Тип «ObservableProperty» пакета «CommunityToolkit.MVVM» позволяет


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

Рисунок 24. Окно регистрации


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

30
Рисунок 25. Окно создания квестов
Присутствует кнопка сохранения QR-кода выбранного задания в pdf файл
для дальнейшего использования.
QR-коды создаются при помощи нашего дополнительного проекта
«QrLib». QR-коды генерируются и записываются в переменную типа Bitmap без
сохранения в файл. Открытие и редактирование pdf файла осуществляется
благодаря библиотеке «ITextSharp».
На рисунке 26 представлено окно назначения заданий студентам. В
верхней части экрана располагаются два выпадающих списка, которые
содержат студентов и квестов, которые могут быть им назначены. В нижней
части находится список всех назначенных на данный момент заданий, а также
кнопка для создания отчета о выполненных студентами квестах.

31
Рисунок 26. Назначение квестов
Создание отчетов в приложении В происходит при помощи «EPPlus».
«EPPlus» – это библиотека .NET Framework/.NET Core для управления
электронными таблицами Office Open XML.
На рисунке 27 показан список всех пользователей, в случае входа под
учетной записью администратора, либо список студентов, в случае входа под
учетной записью с ролью преподавателя.

Рисунок 27. Список пользователей

32
На рисунке 28 можно увидеть экран администраторов для создания новых
учетных записей и редактирования данных существующих пользователей.

Рисунок 28. Редактирование пользователей


Также у каждого пользователя есть доступ к окну настроек, в котором он
может поменять свои данные на рисунке 29.

Рисунок 29. Профиль пользователя


Получение данных из API происходит в интерфейсе «IKipQuestApi», в
котором прописаны необходимые запросы в листинге 6.
33
Листинг 6. Получение данных
public interface IKipQuestApi
{
[Headers("Authorization: Bearer")]
[Get("/user")]
Task<ApiResponse<UserResponse>> GetMe();

[Headers("Authorization: Bearer")]
[Get("/user/{username}")]
Task<ApiResponse<UserResponse>> GetUser(string username);

[Headers("Authorization: Bearer")]
[Get("/user/all")]
Task<ApiResponse<List<UserResponse>>> GetAllUsers(string? role = null);
}

В шапке пишется тип авторизации, в данном случае «Bearer», и путь к


данным с указанием вида запроса. «Get» – для получения, «post» – для отправки
и «patch» – для изменения данных. Далее объявляется функция, которая в
дальнейшем используется в коде приложения.
Для определения работоспособности программы было проведено
тестирование. На рисунках 30–33 продемонстрирован процесс создания
квестов.

Рисунок 30. Заполненные поля для создания квеста

34
Рисунок 31. Результат создания квеста

Рисунок 32. Окно сохранения QR-кода в pdf файл

35
Рисунок 33. Сохраненный QR-код
По результатам тестирования были добавлены сообщения пользователям
о необходимости заполнения всех полей, а также о том, что QR-код нельзя
сгенерировать если задание не было сохранено.
На рисунках 34–38 показано тестирование функции по назначению
квестов студентам.

Рисунок 34. Выбор студента и задания

36
Рисунок 35. Появившийся в списке квест

Рисунок 36. Подтверждение выполнения

Рисунок 37. Окно сохранения Excel отчета


37
Рисунок 38. Отчет о выполненных заданиях студента
В процессе тестирования было добавлено предупреждение о сохранении
в файл, который в данный момент открыт, исправлены ошибки при удалении и
назначении квестов.
Для запуска программы компьютер должен обладать следующими
системными требованиями:
- операционная система: Windows 10;
- оперативная память: 4 ГБ;
- процессор: Intel Pentium IV 2.8 GHz;
- видеокарта: Intel HD 4000.
Запуск программы происходит при помощи .exe файла (напрямую или
через ярлык).
Перед запуском программы необходима её установка, для чего был
создан установщик. Рисунки 39–42 демонстрируют процесс установки.

38
Рисунок 39. Выбор пути установки приложения

Рисунок 40. Выбор дополнительных параметров

39
Рисунок 41. Последний этап установки

Рисунок 42. Завершение установки


Основными функциями приложения являются создание и назначение
заданий студентов. Навигация между окнами приложения осуществляется
инструментами библиотеки WPF UI, посредством использования элемента
40
интерфейса «NavigationCompact» и интерфейса «INavigationService». Для
обратной связи с пользователем используется интерфейс «ISnackbarService»,
который выводит всплывающие окна. Основная логика приложения была
написана, используя паттерн разработки MVVM (Model-View-ViewModel).
Интерфейс программы был создан, используя WPF вкупе с библиотекой
WPF UI. Присутствует вывод сообщений при неполном заполнении форм.
Также есть предупреждение при попытке сохранения информации в уже
открытый файл. На рисунке 43 показана структура проекта.

Рисунок 43. Структура проекта


Также в решении присутствуют еще два проекта. В «KipQuest.Domain»
хранится информация о возвращаемой и запрашиваемой информации API, а
«QRlib» отвечает за генерацию QR-кодов.
2.4 Реализация мобильного приложения
Мобильное приложение для Android и iOS будет иметь авторизацию для
пользователей. Регистрация же будет осуществляться через десктоп
приложение. Всего в мобильном приложении, так же, как и в десктопном, три
41
роли пользователей: администратор, преподаватель, студент. Приложение
будет ориентировано в основном на студентов, которые будут ходить по
помещению с телефонами и сканировать QR-код, но тут также есть отдельные
роли для преподавателя и админа для различных форс-мажорных ситуаций.
Для взаимодействия с API в листинге 7 используется класс «ApiService»,
который отвечает за выполнение HTTP-запросов.
Листинг 7. Класс «ApiService»
class ApiService {
  static const String url = "http://localhost:5184/api";

Метод «login» в листинге 8 отправляет POST-запрос на конечную точку


входа API с указанными именем пользователя и паролем. Если код состояния
ответа равен 200, что указывает на успешный вход в систему, он извлекает
токен доступа и токен обновления из ответа и сохраняет их, используя методы
«TokenService.setAccessToken» и «TokenService.setRefreshToken»
соответственно. Если код состояния ответа не равен 200, он выдает
«ApiException» с подробной информацией об ошибке.
Листинг 8. Метод «login»
static Future login(String username, String password) async {
    try {
      final response = await http.post(
        Uri.parse("$url/auth/login"),
        headers: {"Content-Type": "application/json"},
        body: jsonEncode({
          "username": username,
          "password": password,
        }),
      );
      if (response.statusCode == 200) {
        final tokenStore = TokenStore.fromJson(json.decode(response.body));
        await TokenService.setAccessToken(tokenStore);
        var token = _getRefreshToken(response.headers['set-cookie']!);
        if (token != null) {
          await TokenService.setRefreshToken(token);}
      } else {
        final error = ErrorDto.fromJson(json.decode(response.body));
        throw ApiException(error);
      }
    } finally {} }
42
Метод «completeQuest» в листинге 9 отправляет POST-запрос в конечную
точку завершения задания API с предоставленным идентификатором задания и
логическим значением, указывающим, было ли задание выполнено правильно.
Он включает токен доступа в заголовки запроса для аутентификации. Если код
состояния ответа равен 200, он возвращает завершенный объект «UserQuest».
Листинг 9. Метод «completeQuest»
static Future<UserQuest> completeQuest(int questId, bool isCorrect) async {
    try {
      final token = await TokenService.getAccessToken();

      final response = await http.post(


        Uri.parse("$url/quest/$questId/complete/$isCorrect"),
        headers: {
          "Content-Type": "application/json",
          "Authorization": "bearer $token"
        },
      );
if (response.statusCode == 200) {
        final userQuest = UserQuest.fromJson(json.decode(response.body));
        return userQuest;
      }

Для аутентификации в приложении используются токены. Для


управления токенами был создан класс «TokenService». Используется пакет
«FlutterSecureStorage». Он позволяет считывать, записывать и удалять токены
из защищенного хранилища, обеспечивая безопасный и удобный способ
обработки аутентификации.
При входе в приложение пользователя встречает форма авторизации на
рисунке 44. Имеются проверки на ввод данных.

43
Рисунок 44. Форма авторизации
Виджет «LoginScreen» отвечает за отображение формы входа в систему и
за обработку процесса входа в систему. «LoginScreen» импортирует
необходимые пакеты и файлы из других частей проекта, например виджет
«App» и классы «ApiExceptions», «ApiService». В листинге 10 представлен
фрагмент кода «login_screen».
Листинг 10. Виджет «LoginScreen»
import 'package:flutter/material.dart';
import 'package:kip_quest/pages/App.dart';
import 'package:kip_quest/service/api_exceptions.dart';
import 'package:kip_quest/service/api_service.dart';

class LoginScreen extends StatefulWidget {


  const LoginScreen({Key? key}) : super(key: key);

  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {


  final _formKey = GlobalKey<FormState>();

  late TextEditingController _loginFieldController;


  late TextEditingController _passwordFieldController;

Виджет «LoginScreen» переопределяет метод «createState()» для создания


экземпляра класса «_LoginScreenState», который управляет состоянием виджета
«LoginScreen». «_LoginScreenState» определяет несколько переменных и
44
контроллеров. «_formKey» – это «GlobalKey», используемый для
идентификации и проверки формы. «_loginFieldController» и
«_passwordFieldController» – это экземпляры «TextEditingController»,
используемые для управления полями ввода имени пользователя и пароля.
В методе «initState()» в листинге 11 инициализируются контроллеры для
полей ввода.
Листинг 11. Метод «initState()»
@override
  void initState() {
    super.initState();
    _loginFieldController = TextEditingController();
    _passwordFieldController = TextEditingController();

В методе «dispose()» в листинге 12 контроллеры удаляются для


освобождения ресурсов.
Листинг 12. Метод «dispose()»
@override
  void dispose() {
    _loginFieldController.dispose();
    _passwordFieldController.dispose();
    super.dispose();
  }

Метод «build()» из «_LoginScreenState» в приложении С создает


пользовательский интерфейс для экрана входа в систему.
Он использует виджет «Scaffold» в качестве корневого виджета и
устанавливает заголовок панели. Тело «Scaffold» состоит из виджета «Padding»,
который содержит виджет «Form». Форма использует «_formKey» для
идентификации себя и обработки проверки. Внутри формы есть два виджета
«TextFormField» для полей ввода имени пользователя и пароля. Они
используют соответствующие контроллеры для управления вводом и
предоставления сообщений о проверке с помощью обратного вызова
«validator».

45
Виджет «ElevatedButton» служит кнопкой входа в систему. У него есть
обратный вызов «onPressed», который запускается при нажатии кнопки. Внутри
обратного вызова текущее состояние формы проверяется на валидацию. Если
он действителен, выполняется вызов API для «ApiService.login()» со
значениями имени пользователя и пароля. Если вход в систему выполнен
успешно, вызывается метод «ApiService.getMe()» для извлечения
пользовательских данных, и виджет «App» помещается в стек навигации,
заменяя текущий экран. Если в процессе входа в систему возникает ошибка,
она перехватывается и обрабатывается. Если ошибка является экземпляром
«ApiException», она проверяет конкретные коды ошибок и показывает
пользователю соответствующие сообщения из «SnackBar». Если ошибка не
относится к типу «ApiException», отображается общее сообщение об ошибке.
Производим вход под администратором. Данные для входа: логин
«Yurami», пароль «123». Администратору доступны три вкладки: сканер,
задания, пользователи. На рисунке 45 продемонстрированы возможности
администратора во вкладке заданий. Администратору видны все задания. Он
может их просмотреть, увидеть правильный ответ, а также удалить задание.
Всем пользователям также доступна функция поиска по заданиям.

Рисунок 45. Вкладка «Задания» у администраторов


Во вкладке пользователей на рисунке 46 администратор видит всех
пользователей. Он может менять пользователю его имя и роль. Тут также
имеется проверка ввода данных.

46
Рисунок 46. Вкладка «Пользователи» у администраторов
Теперь производим вход как студент. Данные для входа: логин «dasha»,
пароль «123». У студентов две вкладки: сканер и задания. На рисунке 47
показана вкладка заданий у студентов. Студентам доступны задания,
предназначенные только для них. На данный момент доступны два вида
заданий. Студент может ответить на вопрос, и при неправильном выборе ответа
просмотреть правильный ответ, но поменять свой ответ он уже не сможет.

Рисунок 47. Вкладка «Задания» у студентов


Производим вход под учетной записью преподавателя. Данные для входа:
логин «tga», пароль «123». У преподавателей также три вкладки: сканер,
47
задания и пользователи. На рисунке 48 показана вкладка заданий.
Преподавателю доступны задания, созданные только им самим.

Рисунок 48. Вкладка «Задания» у преподавателей


На рисунке 49 вкладка «Пользователи» у преподавателей. Им доступен
список только из студентов. Изменять какие-либо данные о студентах они не
могут.

48
Рисунок 49. Вкладка «Пользователи» у преподавателей
Виджет «HomeTab» включает в себя сканер QR-кода и функциональность
для добавления заданий на основе отсканированных QR-кодов. Использована
библиотека «mobile_scanner». «_cameraController» создается как экземпляр
«MobileScannerController», который будет управлять функцией сканирования.
Отдельно покажем работу сканнера. У всех пользователей функция
сканера работает по одному принципу: камера телефона подносится к QR-коду,
далее приложение выводит информацию, полученную из QR-кода. На рисунках
50–51 показан пример работы сканера для администратора и преподавателя.

49
Рисунок 50. Работа сканера у преподавателя

Рисунок 51. Работа сканера у администратора

50
Для того чтобы пользоваться приложением, необходимо его скачать.
Надо отсканировать QR-код на рисунке 52. Далее приложение скачается на
Android телефон. Из-за повышенной системы безопасности на данный момент
скачать приложение на iOS невозможно. Но оно полностью функционально и
может быть выпущено в AppStore после прохождения модерации в будущем.
Есть возможность протестировать версию приложения на iOS на эмуляторе.
Минимальные требования для мобильного приложения:
- операционная система: Android или iOS;
- версия Андроид 11.0 и выше;
- версия iOS 14.0 и выше;
- оперативная память не менее 2Гб;
- место на хранилище не менее 300Мб;
- доступ к камере;
- доступ к интернету.

Рисунок 52. QR-код для скачивания приложения на Android


На рисунках 53–55 показан процесс установки приложения.

Рисунок 53. Установка приложения на Android

51
Рисунок 54. Установка приложения на Android

Рисунок 55. Установка приложения на Android


На рисунке 56 показана структура проекта. Основной код написан в «lib».
На рисунке 57 показана структура «lib». Работа с Web API производится в
«service». В «pages» описана работа вкладок приложения. В «models» хранится
представление о данных в базе.

52
Рисунок 56. Структура проекта

Рисунок 57. Структура lib


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

53
ЗАКЛЮЧЕНИЕ
Целью выпускной квалификационной работы являлось создание
конструктора квестов для студентов колледжа.
Для достижения этой цели были выполнены поставленные перед нами
задачи.
Была спроектирована и создана единая база данных в «MySQL»,
«JetBrains DataGrip». Созданная база данных предоставляет структурированное
хранение данных о пользователях, заданиях и их назначениях. Она
обеспечивает эффективное управление информацией, позволяет отслеживать
выполнение заданий и обеспечивает надежность и целостность данных.
Разработали Web API с помощью «Postman», который упрощает процесс
создания, документирования и тестирования API. Это позволяет нам
отправлять HTTP-запросы, просматривать ответы. Также при разработке
использовали «JetBrains Rider». Он предоставляет такие функции:
редактирование кода, отладка и интеграция с системой контроля версий.
Обеспечивает бесперебойное взаимодействие между кодом и базой данных.
Для разработки серверной части API использовали фреймворк «ASP.NET». Он
обеспечивает надежную и масштабируемую платформу. Таким образом, мы
можем создавать контроллеры, определять маршруты, осуществлять
аутентификацию и авторизацию и эффективно обрабатывать данные.
Для разработки настольного приложения для преподавателей были
изучены и использованы: среда разработки «Visual Studio» и «WPF UI». «Visual
Studio» предлагает комплексные инструменты и функции для разработки
настольных приложений. С помощью «WPF UI» мы определили стиль и
элементы управления для пользовательского интерфейса нашего приложения.
Он поддерживает привязку данных, анимацию и различные параметры
настройки пользовательского интерфейса.
Также пригодились знания языка С#, полученные в процессе обучения.

54
Было разработано мобильное приложение для студентов в «Android
Studio». Он предоставляет инструменты, эмуляторы и богатый набор функций
для проектирования, кодирования, отладки и профилирования приложений.
Написано приложение на языке программирования «Dart», в сочетании с
фреймворком «Flutter». «Dart» предлагает такие функции: строгая типизация,
сборка мусора и компиляция точно в срок (JIT). «Flutter» позволил нам создать
визуально привлекательное и высокопроизводительное приложение.
С помощью средства для построения диаграмм были созданы следующие
диаграммы и схемы: функциональные, вариантов использования, структурные.
Для создания Web API были изучены и использованы при разработке:
- утилита для API Postman;
- фреймворк ASP.NET;
- средство управления базой данных MySQL;
- среда разработки JetBrains Rider;
- среда разработки JetBrains DataGrip.
Для создания десктопного приложения были изучены и использованы
при разработке:
- среда разработки Visual Studio;
- графическая библиотека WPF UI.
Для создания мобильного приложения были изучены и использованы при
разработке:
- фреймворк Flutter;
- язык программирования Dart;
- среда разработки Android Studio.
Стоит отметить, что конструктор квестов имеет большой потенциал для
развития и внедрения в будущем.
Достоинства нашего конструктора:
- легкая масштабируемость;
- мультиплатформенность приложений;

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

56
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
Законодательные и нормативные акты:
1. ГОСТ Р 7.0.12-2011 Библиографическая запись. Сокращение слов и
словосочетаний на русском языке. Общие требования и правила. – М.:
Стандартинформ, 2012. – 61 с.
2. ГОСТ 7.1-2003 Библиографическая запись. Библиографическое
описание. Общие требования и правила составления. – М.: Стандартинформ,
2010. – 92 с.
3. ГОСТ 7.32-2017 Отчет о научно-исследовательской работе. Структура
и правила оформления. – М.: Стандартинформ, 2017. – 47 с.
4. ГОСТ 7.82-2001 Библиографическая запись. Библиографическое
описание электронных ресурсов. Общие требования и правила составления. –
М.: ИПК Издательство стандартов, 2001. – 39 с.
5. ГОСТ Р 7.0.100-2018 Библиографическая запись. Библиографическое
описание. Общие требования и правила составления. – М.: Стандартинформ,
2018. – 122 с.
6. ГОСТ Р 7.0.5-2008 Библиографическая ссылка. Общие требования и
правила составления. – М.: Стандартинформ, 2008. – 32 с.
7. Единая система программной документации. – М.: Стандартинформ,
2005. – 128 с.

Учебная и научная литература:


8. Гагарина, Л. Г. Технология разработки программного обеспечения:
учебное пособие / Л.Г. Гагарина, Е.В. Кокорева, Б.Д. Сидорова-Виснадул; под
ред. Л.Г. Гагариной. – Москва: ФОРУМ: ИНФРА-М, 2020. – 400 с.
9. Гниденко, И. Г.  Технологии и методы программирования: учебное
пособие для вузов / И. Г. Гниденко, Ф. Ф. Павлов, Д. Ю. Федоров. – Москва:
Издательство Юрайт, 2020. – 235 с.
10. Гниденко, И. Г.  Технология разработки программного обеспечения:

57
учебное пособие для среднего профессионального образования /
И. Г. Гниденко, Ф. Ф. Павлов, Д. Ю. Федоров. – Москва: Издательство Юрайт,
2020. – 235 с.
11. Гуриков, С. Р. Введение в программирование на языке Visual C#:
учебное пособие / С.Р. Гуриков. – МОСКВА: ФОРУМ: ИНФРА-М, 2020. – 447
с.
12. Иванова, Г.С. Технология программирования: учебник для студентов
вузов обуч. по напр. «Информатика и вычислительная техника» / Г.С. Иванова.
– 3-е изд., стер. – Москва: Кнорус, 2018. – 333 с.
13. Павловская, Т.А. C#. Программирование на языке высокого уровня:
учебник для студентов вузов. – СПб: Питер, 2020. – 432 с.
14. Перлова, О.Н., Ляпина, О.П., Гусева, А.В. Проектирование и
разработка информационных систем: учебник. – 2-е изд, стер. – М.:
Издательский центр «Академия», 2018. – 256 с.

Интернет-документы:
15. Библиотека WPF UI. – [Электронный ресурс]. – Режим доступа:
https://wpfui.lepo.co/ (дата обращения: 22.12.2022)
16. Введение в язык C# и .NET Framework. – [Электронный ресурс]. –
Режим доступа: https://msdn.microsoft.com/ru-ru/library/z1zx9t92.aspx (дата
обращения: 22.12.2022)
17. Иконки и стикеры для бесплатного и платного пользования. –
[Электронный ресурс]. – Режим доступа: https://www.flaticon.com/ (дата
обращения 23.05.2023)
18. Интернет-сервис для построения схем и диаграмм Draw.io. –
[Электронный ресурс]. – Режим доступа: https://www.draw.io/ (дата обращения:
22.12.2022)
19. Официальная документация для работы со Swagger. – [Электронный
ресурс]. – Режим доступа: https://swagger.io/solutions/api-documentation/ (дата
обращения: 01.05.2023)

58
20. Приложение для работы с задачами MS To Do. – [Электронный
ресурс]. – Режим доступа: https://todo.microsoft.com/tasks/ (дата обращения:
01.05.2023)
21. Руководство по программированию в WPF. – [Электронный ресурс]. –
Режим доступа: https://metanit.com/sharp/wpf/ (дата обращения: 01.05.2023)
22. Руководство по работе в среде Visual Studio. – [Электронный ресурс].
– Режим доступа: https://docs.microsoft.com/ru-ru/visualstudio/ (дата обращения:
01.05.2023)
23. Руководство по работе с языком программирования Dart. –
[Электронный ресурс]. – Режим доступа: https://dart.dev/ (дата обращения:
01.05.2023)
24. Среда разработки Android Studio. – [Электронный ресурс]. – Режим
доступа: https://developer.android.com/studio (дата обращения: 01.05.2023)
25. Среда разработки JetBrains DataGrip. – [Электронный ресурс]. –
Режим доступа: https://www.jetbrains.com/datagrip/ (дата обращения: 01.05.2023)
26. Фреймворк Flutter. – [Электронный ресурс]. – Режим доступа:
https://flutter.dev/ (дата обращения: 01.05.2023)

59
ПРИЛОЖЕНИЕ
Приложение А
Словарь базы данных
В таблицах 1–4 представлен словарь данных базы данных.
Таблица 1. Словарь данных таблицы Users
Ключ Название Тип данных Обяз. Комментарии
столбца
Первичный UserID int Да Суррогатный первичный ключ
Username longtext Да Псевдоним
PasswordHash longtext Да Хэшированный пароль
UserRole varchar(64) Да Роль пользователя
FirstName longtext Да Имя
LastName longtext Да Фамилия
Внешний SecondName longtext Да Отчество

Таблица 2. Словарь данных таблицы Quests


Ключ Название Тип данных Обяз. Комментарии
столбца
Первичный QuestID int Да Суррогатный первичный ключ
JSONData longtext Да Данные задания в json формат
OwnerID int Да Вторичный ключ к таблице Users
ShortLabel longtext Да Краткое наименование
QuestType varchar(64) Да Тип квеста

Таблица 3. Словарь данных таблицы RefreshTokens


Ключ Название Тип данных Обяз. Комментарии
столбца
Первичный RefreshTokenI int Да Суррогатный первичный ключ
D
Token longtext Да Токен
Created datetime(6) Да Дата создания токена
Expires datetime(6) Да Дата истечения токена

Таблица 4. Словарь данных таблицы UserQuest


Ключ Название Тип данных Обяз Комментарии
столбца .
Первичный UserQuestID int Да Суррогатный первичный ключ
UserID int Да Вторичный ключ к таблице Users
QuestID int Да Вторичный ключ к таблице Quests
IsComplete tinyint(1) Да Статус завершения задания
GivedTime datetime(6) Да Время выдачи задания
CompletedTim datetime(6) Нет Время выполнения задания
60
e
Внешний IsCorrect tinyint(1) Нет Статус правильности задания
Приложение В
Фрагмент листинга кода десктопного приложения
Листинг кода для создания отчетов.
using (var xlPackage = new ExcelPackage(file))
{
int i = 0;
foreach (var student in allStudensResponse.Content)
{
var worksheet = xlPackage.Workbook.Worksheets.Add($"{student.LastName} {student.FirstName}");

var row = 7;

var dataToExport = new List<ExportQuestData>();


var amountOfCorrectComplitedQuests = 0;

foreach(var quest in student.UserQuests)


{
dataToExport.Add(new ExportQuestData(quest));
if(quest.isComplete)
{
if(quest.isCorrect.Value)
{
amountOfCorrectComplitedQuests++;
}
}
}

worksheet.Cells.Style.Font.Name = "Times New Roman";


worksheet.Cells.Style.Font.Size = 12;
worksheet.Cells.Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
worksheet.Cells.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
worksheet.Column(1).Width = 14;
worksheet.Column(2).Width = 14;
worksheet.Column(3).Width = 14;
worksheet.Column(4).Width = 18;
worksheet.Column(5).Width = 18;

//"ФИО студента"
worksheet.Cells["A1:A2"].Merge = true;
worksheet.Cells["A1"].Value = "ФИО студента";
worksheet.Cells["A1:A2"].Style.WrapText = true;

//ФИО
worksheet.Cells["B1"].Value = $"{student.LastName} {student.FirstName} {student.SecondName}";
worksheet.Cells["B1:D2"].Merge = true;
worksheet.Cells["B1:D2"].Style.Font.Size = 16;
worksheet.Cells["A1:D2"].Style.Border.Bottom.Style =
worksheet.Cells["B1:D2"].Style.Border.Bottom.Style =
worksheet.Cells["B1:D2"].Style.Border.Right.Style = ExcelBorderStyle.Thick;

//Всего выполнено:
worksheet.Cells["A3:B3"].Value = "Всего выполнено:";
worksheet.Cells["A3:B3"].Merge = true;
worksheet.Cells["A3:B3"].Style.WrapText = true;

worksheet.Cells["A4:B4"].Style.Numberformat.Format = "0";

61
worksheet.Cells["A4:B4"].Value = amountOfCorrectComplitedQuests;

if(amountOfCorrectComplitedQuests / (float)student.UserQuests.Count < 0.30)


{
worksheet.Cells["A4:B4"].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells["A4:B4"].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(192, 0, 0));
}
else if(amountOfCorrectComplitedQuests / (float)student.UserQuests.Count > 0.70)
{
worksheet.Cells["A4:B4"].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells["A4:B4"].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(169, 208, 142));
}
else
{
worksheet.Cells["A4:B4"].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells["A4:B4"].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(255, 217, 102));
}

worksheet.Cells["A4:B4"].Merge = true;
worksheet.Cells["A4:B4"].Style.Font.Size = 16;

//Всего назначено
worksheet.Cells["C3:D3"].Value = "Всего назначено:";
worksheet.Cells["C3:D3"].Merge = true;
worksheet.Cells["C3:D3"].Style.WrapText = true;

worksheet.Cells["C4:D4"].Style.Numberformat.Format = "0";
worksheet.Cells["C4:D4"].Value = student.UserQuests.Count;
worksheet.Cells["C4:D4"].Merge = true;
worksheet.Cells["C4:D4"].Style.Font.Size = 16;

worksheet.Cells["B3:B4"].Style.Border.Right.Style =
worksheet.Cells["D3:D4"].Style.Border.Right.Style = ExcelBorderStyle.Thick;

/*Заголовок таблицы*/
//Название
worksheet.Cells["A5:A6"].Value = "Название";
worksheet.Cells["A5:A6"].Merge = true;
//Статус
worksheet.Cells["B5:C5"].Value = "Статус";
worksheet.Cells["B5:C5"].Merge = true;
worksheet.Cells["B6"].Value = "Завершение";
worksheet.Cells["C6"].Value = "Правильность";

//Время назначения
worksheet.Cells["D5:D6"].Value = "Время назначения";
worksheet.Cells["D5:D6"].Merge = true;
worksheet.Cells["D5:D6"].Style.WrapText = true;
//Время назначения
worksheet.Cells["E5:E6"].Value = "Время окончания";
worksheet.Cells["E5:E6"].Merge = true;
worksheet.Cells["E5:E6"].Style.WrapText = true;
worksheet.Cells["A5:E6"].Style.Border.Bottom.Style =
worksheet.Cells["A5:E6"].Style.Border.Top.Style =
worksheet.Cells["A5:E6"].Style.Border.Left.Style =
worksheet.Cells["A5:E6"].Style.Border.Right.Style = ExcelBorderStyle.Thin;

worksheet.Cells["A5:E6"].Style.Border.Bottom.Style =
worksheet.Cells["A5:E6"].Style.Border.Top.Style =
worksheet.Cells["E5:E6"].Style.Border.Right.Style = ExcelBorderStyle.Thick;
foreach (var quest in dataToExport)
{
worksheet.Cells[row, 1].Value = quest.name;
worksheet.Cells[row, 2].Value = quest.accomplishmentStatus;
worksheet.Cells[row, 3].Value = quest.сorrectionStatus;
62
worksheet.Cells[row, 4].Style.Numberformat.Format = "yyyy-mm-dd h:mm";
worksheet.Cells[row, 5].Style.Numberformat.Format = "yyyy-mm-dd h:mm";
worksheet.Cells[row, 4].Value = quest.timeOfAssignment;
worksheet.Cells[row, 5].Value = quest.finalTime;
if(quest.accomplishmentStatus == "+")
{
if (quest.сorrectionStatus == "+")
{
worksheet.Cells[row, 1, row, 5].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[row, 1, row, 5].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(169, 208,
142));
}
else
{
worksheet.Cells[row, 1, row, 5].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[row, 1, row, 5].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(192, 0, 0));
}
}
else
{
worksheet.Cells[row, 1, row, 5].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[row, 1, row, 5].Style.Fill.BackgroundColor.SetColor(Color.FromArgb(255, 217,
102));
}
worksheet.Cells[row, 1, row, 5].Style.Border.Right.Style =
worksheet.Cells[row, 1, row, 5].Style.Border.Left.Style =
worksheet.Cells[row, 1, row, 5].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
row++;
}
i++;
}
await xlPackage.SaveAsync();
}

63
Приложение С
Фрагмент листинга кода мобильного приложения
Листинг кода метода «build()» из «_LoginScreenState».
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Вход"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              TextFormField(
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Имя пользователя',
                ),
                controller: _loginFieldController,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return "Имя пользователя не может быть пустым";
                  }
                  return null;
                },
              ),
              const SizedBox(
                height: 10,
              ),
              TextFormField(
                obscureText: true,
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Пароль',
                ),
                controller: _passwordFieldController,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return "Пароль не может быть пустым";
                  }
                  return null;
                },
              ),
              const SizedBox(

64
                height: 10,
              ),
              ElevatedButton(
                onPressed: () async {
                  if (_formKey.currentState!.validate()) {
                    try {
                      await ApiService
                          .login(
                            _loginFieldController.text,
                            _passwordFieldController.text,
                          );
                      ApiService.getMe().then((value) => {
                        Navigator.of(context).pushReplacement(
                          MaterialPageRoute(
                            builder: (context) => App(user: value),
                          ),
                        )
                      });

                    } catch (e) {
                      if (e is ApiException) {
                        final error = e.error;
                        if (error.errorCodes != null) {
                          if (error.errorCodes!.first == "User.NotFound") {
                            ScaffoldMessenger.of(context).showSnackBar(const
SnackBar(
                              backgroundColor: Colors.red,
                              content: Text('Пользователь не найден'),
                            ));
                          } else if (error.errorCodes!.first ==
"Auth.InvalidCredentials") {
                            ScaffoldMessenger.of(context).showSnackBar(const
SnackBar(
                              backgroundColor: Colors.red,
                              content: Text('Неправильный пароль'),
                            ));
                          } else {
                            ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                              backgroundColor: Colors.red,
                              content: Text(error.title),
                            ));
                          }
                        }
                      } else {
                        ScaffoldMessenger.of(context).showSnackBar(const
SnackBar(
                          backgroundColor: Colors.red,
                          content: Text("Возникла ошибка при подключении к
серверу"),
                        ));

65
                      }
                    }
                  }
                },
                child: const Text("Войти"),
              ),
            ],
          ),
        ),
      ),
    );
  }

66
Приложение D
Презентация для защиты выпускной квалификационной работы
На рисунках 58–76 представлены слайды презентации для защиты
выпускной квалификационной работы.

Рисунок 58. Титульный слайд

Рисунок 59. Актуальность

67
Рисунок 60. Цели и задачи работы

Рисунок 61. Проблемы и способы их решения

68
Рисунок 62. Инструментальные средства разработки

Рисунок 63. Инструментальные средства разработки десктопного


приложения

69
Рисунок 64. Инструментальные средства разработки мобильного
приложения

Рисунок 65. Инструментальные средства разработки Web API

70
Рисунок 66. Диаграмма базы данных

Рисунок 67. Схема работы приложения

71
Рисунок 68. Пример запроса

Рисунок 69. Пример запроса

72
Рисунок 70. Пример кода

Рисунок 71. Пример интерфейса десктопного приложения

73
Рисунок 72. Пример интерфейса мобильного приложения

Рисунок 73. Пример QR-кода с заданием

74
Рисунок 74. Пример кода

Рисунок 75. Результаты работы

75
Рисунок 76. Заключительный слайд

76

Вам также может понравиться