аааа

Скачать как docx, pdf или txt
Скачать как docx, pdf или txt
Вы находитесь на странице: 1из 54

СОДЕРЖАНИЕ

ВВЕДЕНИЕ ................................................................................................................ 6
1 Постановка задачи................................................................................................... 7
2 Моделирование проектируемой системы........................................................... 10
3 Разработка функциональных требований........................................................... 12
4 Обоснование выбора средств реализации........................................................... 14
5 Структура программы........................................................................................... 16
6 Схемы алгоритмов................................................................................................. 17
7 Результаты выполнения программы.................................................................... 21
ЗАКЛЮЧЕНИЕ......................................................................................................... 24
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ............................................... 25
ПРИЛОЖЕНИЕ А.................................................................................................... 27
ВВЕДЕНИЕ

В настоящее время доступность компьютерной техники становится все выше. Компьютеры


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

Современные предприятия, такие как АО АВЭКС, сталкиваются с необходимостью


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

Использование автоматизированной информационной системы на предприятии АО АВЭКС


позволит добиться следующих преимуществ:

 структурированное хранение информации;


 быстрый доступ к данным через удобный интерфейс;
 повышение оперативности учёта;
 снижение вероятности ошибок и потерь данных.

Объектом исследования данной работы является АО АВЭКС, имеющее разветвлённую


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

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


автоматизации учета данных сотрудников, инструкций, публикаций и отпусков на базе
СУБД MySQL.

Для достижения поставленной цели необходимо решить следующие задачи:

 провести анализ предметной области;


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

5
1 Постановка задачи

Предметная область — это часть реального мира, исследуемая в рамках конкретного проекта
и описываемая средствами информационной системы.

Тема предметной области: «Автоматизация учета сотрудников, отпусков и должностей на


предприятии». На предприятии АО АВЭКС требуется систематизация данных о
сотрудниках, их контактной информации, занимаемых должностях и периодах отпусков.
Система должна позволять администратору управлять данными, а сотрудникам —
просматривать и обновлять свои данные.

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


следующие основные таблицы:

1. Пользователи (users): информация о сотрудниках, их учетных данных и должностях:


o Идентификатор (id);
o Имя пользователя (username);
o Пароль (password);
o ФИО (fio);
o Дата рождения (date_of_birth);
o Номер телефона (phone_number);
o Электронная почта (email);
o Должность (position);
o Уровень доступа (ur_dost);
o Дата создания учетной записи (created_at);
o Дата обновления учетной записи (updated_at);
o Отпуск (vacation, ссылочный ключ на таблицу отпусков).
2. Отпуска (vacation_days): информация о периодах отпусков сотрудников:
o Идентификатор (id);
o Дата начала отпуска (start_date);
o Дата окончания отпуска (end_date).

Система должна обеспечивать выполнение следующих функций:

Администратор:

 Добавление, изменение и удаление записей о сотрудниках;


 Управление данными о периодах отпусков сотрудников;
 Просмотр всех данных системы.

Сотрудник:

 Просмотр и обновление личных данных, включая ФИО, контактную информацию и


должность;
 Просмотр данных о своем отпуске.

6
Для реализации проекта используются Python с микрофреймворком Flask для создания
серверной части, а также HTML и CSS для разработки клиентской стороны с удобным
графическим интерфейсом. Данные хранятся в базе данных, управляемой с
помощью MySQL.

Цель проекта — автоматизировать процесс учета сотрудников и отпусков на предприятии


АО АВЭКС, что позволит повысить точность и оперативность работы с данными,
минимизировать количество ошибок и ускорить обработку информации.

7
2 Моделирование проектируемой системы

Проектирование автоматизированной системы учета сотрудников и отпусков для АО


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

1. Проектирование структуры системы


Система спроектирована как многослойная архитектура, включающая:
o Пользовательский уровень — графический интерфейс, реализованный с
использованием HTML, CSS для фронтенда и Flask для серверной логики.
Интерфейс предоставляет пользователям доступ к основным функциям
системы, таким как добавление, изменение и удаление данных.
o Логический уровень — бизнес-логика, реализованная на Python с
использованием Flask, обеспечивает обработку данных, включая валидацию,
форматирование и взаимодействие с базой данных.
o Уровень данных — система управления базами данных,
использующая MySQL для хранения информации о сотрудниках и их
отпусках.
2. Функциональные компоненты системы
В рамках системы были разработаны модули, отвечающие за выполнение следующих
функций:
o Управление пользователями: регистрация, авторизация и управление
данными пользователей.
o Учет отпусков: хранение данных о периодах отпусков сотрудников, включая
даты начала и окончания.
o Управление данными: добавление, редактирование и удаление записей.
3. Проектирование пользовательского интерфейса
Для взаимодействия пользователя с системой был разработан удобный графический
интерфейс. Основные принципы проектирования интерфейса:
o Простота и интуитивность, чтобы минимизировать время обучения
пользователя.
o Визуальное представление данных в форме таблиц и форм.
o Поддержка операций с данными через кнопки управления, такие как
«Добавить», «Изменить» и «Удалить».
4. Интеграция с вычислительной средой
Система спроектирована для работы на персональных компьютерах с ОС Windows и
Linux. Использование MySQL в качестве СУБД обеспечивает надежное хранение
данных, а Flask с HTML/CSS позволяет создать удобный и отзывчивый
пользовательский интерфейс, обеспечивая переносимость и простоту развертывания.
5. Обеспечение безопасности и надежности
Для предотвращения несанкционированного доступа к данным реализована система
авторизации пользователей. Логины и пароли хранятся в базе данных в
зашифрованном виде. Все операции с базой данных проверяются на корректность, что
предотвращает возможные ошибки при вводе данных.

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

Разработанная система позволяет автоматизировать процессы учета сотрудников и отпусков,


упрощает доступ к данным и минимизирует вероятность ошибок при их обработке. Ее
гибкость и масштабируемость позволяют адаптировать решение к изменяющимся
требованиям АО АВЭКС.

На рисунке 2.1 представлена диаграмма IDEF1X базы данных по учету


сотрудников и отпусков.

Рисунок 2.1 − Диаграмма IDEF1X


На рисунке 2.2 представлена диаграмма IDEF0 системы по учету
сотрудников и отпусков.

Рисунок 2.2 − Диаграмма IDEF0

9
На рисунке 2.3 представлена декомпозиция IDEF0 системы по учету
сотрудников и отпусков.

Рисунок 2.3 − Декомпозиция IDEF0

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

Разрабатываемое программное обеспечение предназначено для автоматизации процессов


учета сотрудников, их должностей и отпусков на предприятии АО АВЭКС. Основное
функциональное назначение ПО включает сбор, хранение, обработку и предоставление
информации о сотрудниках и их отпусках.

Эксплуатационное назначение ПО заключается в использовании его администраторами и


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

Требования к функциональным характеристикам:

1. Для администратора:
o Возможность добавления, изменения и удаления записей о сотрудниках;
o Управление данными об отпусках сотрудников;
o Просмотр всех данных, хранящихся в системе, с возможностью поиска и
фильтрации.
2. Для сотрудников:
o Просмотр и обновление личных данных, включая ФИО, контактную
информацию и должность;
o Просмотр данных о своих отпусках.
3. Общие функции:
o Авторизация пользователей с разными уровнями доступа (администратор и
сотрудник);
o Валидация данных при вводе и их проверка на соответствие заданным
правилам;
o Уведомления о результатах операций (успех или ошибка).

Требования к надежности:

 Устойчивое функционирование. Система должна обеспечивать бесперебойную


работу при стандартных условиях эксплуатации.
 Восстановление после сбоев. Возможность автоматического сохранения изменений в
случае непредвиденного завершения работы системы;
 Быстрое восстановление системы из резервной копии данных.

Требования к составу и параметрам технических средств:

1. Минимальные характеристики оборудования:


o Операционная система: Windows 10 / Linux Ubuntu 18.04 и выше;
o Процессор: с тактовой частотой не ниже 2 ГГц;
o Оперативная память: не менее 4 ГБ;
o Свободное место на диске: не менее 500 МБ.
2. Средства разработки:

11
o Python 3.9+ с использованием фреймворка Flask для серверной части
и HTML, CSS для интерфейса;
o СУБД MySQL для хранения данных.

Требования к информационной и программной совместимости:

 Совместимость с базой данных. Программное обеспечение должно быть


интегрировано с СУБД MySQL версии 8.0 и выше.
 Совместимость с программными средствами. Возможность работы на устройствах
с установленной библиотекой Flask и поддерживающими HTML/CSS.

Требования к программной документации:

1. Комментарии к коду. Весь исходный код должен быть снабжен комментариями,


поясняющими основные функции и алгоритмы работы системы.
2. Сопроводительная документация:
o Руководство пользователя с описанием основных функций системы;
o Инструкции по установке и настройке ПО;
o Техническое описание структуры базы данных и реализованных модулей.

Требования к интерфейсу:

 Графический интерфейс должен быть интуитивно понятным и удобным как для


администратора, так и для сотрудника.
 Все действия пользователя (например, добавление, изменение, удаление данных)
должны сопровождаться уведомлениями об успехе или ошибке операции.

12
4 Обоснование выбора средств реализации

Для реализации программного обеспечения по автоматизации учета сотрудников и отпусков


в АО АВЭКС были выбраны следующие основные средства разработки:

1. СУБД MySQL Workbench.


MySQL Workbench был выбран для проектирования и управления реляционной базой
данных. Этот инструмент позволяет визуально моделировать структуру базы данных,
разрабатывать сложные запросы, а также осуществлять администрирование и
управление данными.
Причины выбора MySQL Workbench:
o Удобный графический интерфейс для проектирования и управления базами
данных.
o Наличие встроенных инструментов для тестирования SQL-запросов и
оптимизации их производительности.
o Широкая поддержка стандартов SQL, что упрощает выполнение сложных
операций над данными.
o Возможность интеграции с Python через библиотеку mysql-connector-python,
что облегчает доступ к базе данных из приложения.
2. Язык программирования Python.
Python был выбран в качестве основного языка программирования благодаря своей
универсальности и наличию множества библиотек для работы с базами данных,
создания серверной логики и обработки данных.
Преимущества Python:
o Простота синтаксиса, что ускоряет процесс разработки.
o Наличие библиотек для подключения к MySQL (mysql-connector-python), что
делает работу с базой данных надежной и гибкой.
o Поддержка различных парадигм программирования, включая объектно-
ориентированное и процедурное.
o Широкая поддержка веб-разработки, в частности через фреймворк Flask, что
позволяет быстро разрабатывать веб-приложения.
3. Фреймворк Flask.
Flask был выбран для реализации серверной части приложения. Этот микрофреймворк
на Python идеально подходит для небольших и средних веб-приложений, обеспечивая
простоту и гибкость.
Причины выбора Flask:
o Легкость и минимализм, позволяющие разрабатывать приложение с
минимальными затратами времени.
o Возможность легко интегрировать с различными библиотеками для работы с
базами данных, такими как Flask-MySQLdb.
o Простота в создании RESTful API, которое требуется для взаимодействия
фронтенда с сервером.
4. HTML и CSS.
Для создания веб-интерфейса были выбраны HTML и CSS. Эти технологии
позволяют разрабатывать структурированные и стилизованные веб-страницы,

13
предоставляющие удобный интерфейс для пользователей.
Причины выбора HTML и CSS:
o HTML предоставляет все необходимые элементы для создания структуры веб-
страниц.
o CSS обеспечивает гибкость в стилизации интерфейса, позволяя создавать
привлекательные и интуитивно понятные страницы.
o Поддержка всех современных веб-браузеров и мобильных устройств, что
делает интерфейс доступным на разных платформах.
5. Среда разработки PyCharm.
PyCharm был использован как основная среда разработки благодаря удобным
инструментам для написания, отладки и тестирования кода.
Преимущества PyCharm:
o Подсветка синтаксиса и автодополнение, что ускоряет написание кода.
o Встроенные средства для отладки и тестирования, упрощающие процесс
устранения ошибок.
o Поддержка управления версиями (например, через Git), что облегчает
командную работу.

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


доступностью. Совокупное применение MySQL Workbench для работы с базой
данных, Python и Flask для разработки серверной части, HTML и CSS для создания
интерфейса, а также PyCharm для эффективной разработки позволило создать качественное
и функциональное решение, удовлетворяющее требованиям автоматизации учета
сотрудников и их отпусков в АО АВЭКС.

14
5 Структура программы

Программа состоит из следующих основных файлов и модулей:

1. Основные файлы приложения:

 app.py — главный файл программы, отвечает за запуск приложения и


инициализацию всех компонентов.

 database.py — модуль для работы с базой данных, содержит функции


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

2. Модули пользовательского интерфейса:

 auth_window.py — окно авторизации пользователей, реализует


проверку учетных данных.

 register_window.py — окно регистрации новых пользователей с


возможностью добавления информации в базу данных.

 admin_window.py — основное окно администратора,


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

 user_window.py — окно для работы пользователя с данными,


ограниченное редактированием только собственной информации.

3. Диалоговые окна:

 add_record_dialog.py — окно добавления новых записей в базу


данных.

 edit_record_dialog.py — окно редактирования существующих записей.

4. Среда разработки. Каталог .venv — виртуальное окружение проекта,


включающее зависимости и настройки среды разработки.

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

На рисунке 5.1 изображена структура программы.

Рисунок 5.1 − Структура программы

16
6 Схемы алгоритмов

На рисунке 6.1 представлена схема алгоритма программы из файла


auth_window.py.

Начало

login()

register()

Конец

Рисунок 6.1 − Схема алгоритмов auth_window.py

На рисунке 6.2 изображена схема алгоритмов функции register().

Начало

self.register_window =
RegisterWindow()
self.register_window.show()
self.close()

Конец

Рисунок 6.2 − Схема алгоритмов функции register()

17
На рисунке 6.3 изображена схема алгоритмов функции login().

Начало

username =
self.input_username.text()
password =
self.input_password.text()
user =
self.db.login_user(usernam
e, password)

Неверное имя
user Нет пользователя
или пароль.

Да
user_id, role =
user["id"],
user["ur_dost"]

pr = pr *
role == 0 Нет
* Z[i, i]

Да
self.user_window = self.admin_window
UserWindow(user_id) = AdminWindow()
self.user_window.show self.admin_window.
() show()

self.close()

Возврат

Рисунок 6.3 − Схема алгоритмов функции login()

18
7 Результаты выполнения программы

Важным аспектом является работоспособность программы –


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

На рисунке 7.1 показана работа с формой «Авторизация» . На данной


форме пароль скрывается точками.

Рисунок 7.1 – Успешная работа с формой «Авторизация»

На рисунке 7.2 показана ошибка, которая возникает при неверной паре


логин и пароль, а также при пустых полях.

19
Рисунок 7.2 – Ошибка при вводе логина и пароля

При отсутствии логина и пароля пользователь может нажать на кнопку


«Регистрация» и перейти на форму регистрации. На рисунке 7.3
продемонстрирована данная форма.

Рисунок 7.3 – Форма регистрации

20
Если какое-либо из обязательных полей не заполнено, то возникает
сообщение о соответствующей ошибке, которое представлено на рисунке 7.4

Рисунок 7.4 – Ошибка при невыполнении необходимых условий

После регистрации пользователь возвращается на форму авторизации и


выполняет вход. Уровни доступа определяет администратор, вход выполняется
согласно им. При переходе на форму администратора открывается окно
представленное на рисунке 7.5.

21
Рисунок 7.5 – Панель администратора

При нажатии кнопки «Добавить» открывается форма для добавления


сотрудника, которая представлена на рисунке 7.6.

Рисунок 7.6 – Форма добавления сотрудника

22
При добавлении пользователя все данные должны быть заполнены. На
рисунке 7.7 изображен вывод ошибки при оставленных пустых полях.

Рисунок 7.7 – Предупреждение о пустых полях

На рисунке 7.8 представлено успешное добавление пользователя.

Рисунок 7.8 – Успешное добавление пользователя

23
Если нажать на кнопку изменения пользователя(или удаления), то будет
отображено сообщение о том, что нужно кого-то выбрать. Это представлено на
рисунке 7.9.

Рисунок 7.9 – Сообщение при отсутствии выбора пользователя

На рисунке 7.10 представлено успешное удаление пользователя.

На рисунке 7.10 представлено успешное удаление пользователя.

24
При авторизации под логином и паролем пользователя открывается
форма, которая представлена на рисунке 7.11.

Рисунок 7.11 – Форма пользователя

На рисунке 7.12 представлено успешное изменение пользователя.

Рисунок 7.12 – Изменение пользователя

25
ЗАКЛЮЧЕНИЕ

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


автоматизации процессов управления данными сотрудников и администраторов на
предприятии АО «АВЭКС». Созданная система позволяет эффективно организовать
хранение, обработку и обновление данных, обеспечивая удобный пользовательский
интерфейс для взаимодействия с базой данных.

Разработка включала проектирование структуры базы данных, реализацию программных


модулей, а также создание интерфейсов для выполнения различных задач, таких как
добавление, редактирование и удаление записей. Для хранения данных была выбрана СУБД
MySQL, которая обеспечила надежность и скорость обработки информации. В качестве
серверной части использован Python с фреймворком Flask, что позволило эффективно
обрабатывать запросы и взаимодействовать с базой данных. Для создания графического
интерфейса использовались HTML, CSS и JavaScript, что обеспечило гибкость и удобство в
использовании.

Основные преимущества разработанной системы:

 Структурированное хранение данных сотрудников и администраторов.


 Возможность разграничения доступа для разных типов пользователей (администратор
и пользователь).
 Удобный интерфейс для работы с записями.
 Минимизация ошибок за счет автоматизации рутинных процессов.

Система прошла тестирование и полностью удовлетворяет поставленным функциональным


требованиям. Её внедрение позволит предприятию АО «АВЭКС» ускорить процессы работы
с данными, снизить вероятность ошибок, связанных с ручным вводом, и повысить
эффективность управления данными сотрудников.

В дальнейшем возможна доработка системы, включая расширение функциональности,


добавление новых модулей и интеграцию с другими информационными системами
предприятия.

26
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

1) Готтлиб, П. Базы данных. Проектирование, реализация и сопровождение. —


СПб: Питер, 2020.

2) Олифер, В. Г., Олифер, Н. А. Компьютерные сети. Принципы, технологии,


протоколы. — М.: Финансы и статистика, 2019.

3) Date, C. J. An Introduction to Database Systems. — Pearson Education, 2014.

4) Шилдт, Г. Python. Полное руководство. — СПб: Питер, 2021.

5) Фейерштейн, Д. Изучаем PyQt: Программирование GUI на Python. —


O’Reilly Media, 2019.

6) Официальная документация по MySQL. MySQL Documentation

7) Официальная документация по PyQt. PyQt Documentation

8) Гринберг, М. Fluent Python: Лучшие методы Python-программирования. —


O’Reilly Media, 2017.

9) Уокер, Р. Методы тестирования программного обеспечения. — М.:


Диалектика, 2018.

10)Официальная документация по SQL. SQL Tutorial.

27
ПРИЛОЖЕНИЕ А
(обязательное)

Листинг программы

28
add_record_dialog.py

from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QLabel,


QDialogButtonBox, QMessageBox

class AddRecordDialog(QDialog):

def __init__(self, table_name, db, parent=None):

super().__init__(parent)

self.db = db

self.table_name = table_name

self.setWindowTitle("Добавить нового пользователя")

self.form_layout = QFormLayout(self)

self.fields = {}

columns = ['username', 'passwrd', 'fio', 'date_of_birth', 'phone_number', 'email',


'positionn', 'vacation']

for column in columns:

label = QLabel(column.capitalize())

field = QLineEdit()

self.form_layout.addRow(label, field)

self.fields[column] = field

29
button_box = QDialogButtonBox(QDialogButtonBox.Ok |
QDialogButtonBox.Cancel)

button_box.accepted.connect(self.accept)

button_box.rejected.connect(self.reject)

self.form_layout.addRow(button_box)

def accept(self):

new_data = {}

for column, field in self.fields.items():

value = field.text()

if value == "" or value.lower() == "none":

new_data[column] = None

else:

new_data[column] = value

from datetime import datetime

new_data['created_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

try:

self.db.insert_data(self.table_name, new_data)

30
QMessageBox.information(self, "Успех", "Новый пользователь
добавлен!")

self.close()

except Exception as e:

QMessageBox.critical(self, "Ошибка", f"Не удалось добавить


пользователя: {e}")

self.reject()

admin_window.py

import ast

import re

from PyQt5.QtWidgets import (

QMainWindow, QTabWidget, QVBoxLayout, QWidget, QListWidget,

QPushButton, QHBoxLayout, QMessageBox

from database import Database

from edit_record_dialog import EditRecordDialog

from add_record_dialog import AddRecordDialog

31
class AdminWindow(QMainWindow):

def __init__(self):

super().__init__()

self.setWindowTitle("Панель администратора")

self.setGeometry(100, 100, 600, 400)

self.db = Database()

self.tab_widget = QTabWidget()

self.setCentralWidget(self.tab_widget)

self.categories_tab = self.create_tab("categories")

self.instructions_tab = self.create_tab("instructions")

self.vacation_days_tab = self.create_tab("vacation_days")

self.posts_tab = self.create_tab("posts")

self.users_tab = self.create_tab("users")

self.tab_widget.addTab(self.categories_tab, "Категории")

self.tab_widget.addTab(self.instructions_tab, "Инструкции")

self.tab_widget.addTab(self.vacation_days_tab, "Дни отпуска")

self.tab_widget.addTab(self.posts_tab, "Публикации")

self.tab_widget.addTab(self.users_tab, "Пользователи")

32
def create_tab(self, table_name):

widget = QWidget()

layout = QVBoxLayout()

list_widget = QListWidget()

layout.addWidget(list_widget)

buttons_layout = QHBoxLayout()

add_button = QPushButton("Добавить")

edit_button = QPushButton("Изменить")

delete_button = QPushButton("Удалить")

buttons_layout.addWidget(add_button)

buttons_layout.addWidget(edit_button)

buttons_layout.addWidget(delete_button)

layout.addLayout(buttons_layout)

self.load_table_data(table_name, list_widget)

add_button.clicked.connect(lambda: self.add_row(table_name, list_widget))

edit_button.clicked.connect(lambda: self.edit_row(table_name, list_widget))

delete_button.clicked.connect(lambda: self.delete_row(table_name, list_widget))

33
widget.setLayout(layout)

return widget

def load_table_data(self, table_name, list_widget):

list_widget.clear()

try:

data = self.db.get_table_data(table_name)

for row in data:

list_widget.addItem(str(row))

except Exception as e:

QMessageBox.critical(self, "Ошибка", f"Не удалось загрузить данные:


{e}")

def add_row(self, table_name, list_widget):

dialog = AddRecordDialog(table_name, self.db, self)

dialog.exec_()

def edit_row(self, table_name, list_widget):

current_item = list_widget.currentItem()

if not current_item:

QMessageBox.warning(self, "Внимание", "Выберите запись для


редактирования.")

return

34
raw_data = current_item.text().strip()

try:

row_data = eval(raw_data)

except Exception as e:

print(f"Error: {e}")

QMessageBox.critical(self, "Ошибка", f"Не удалось разобрать данные:


{e}")

return

dialog = EditRecordDialog(row_data, table_name, self.db, self)

dialog.exec_()

import re

def delete_row(self, table_name, list_widget):

current_item = list_widget.currentItem()

if not current_item:

QMessageBox.warning(self, "Внимание", "Выберите запись для


удаления.")

return

raw_data = current_item.text().strip()

35
match = re.search(r"'id': (\d+)", raw_data) # Ищем id: <число> в строке

if match:

record_id = int(match.group(1)) # Извлекаем ID как число

else:

QMessageBox.critical(self, "Ошибка", "Не удалось извлечь ID из записи.")

return

# Удаляем запись по ID

if self.db.delete_data_by_id(table_name, record_id):

QMessageBox.information(self, "Успех", f"Запись с ID {record_id}


успешно удалена!")

self.load_table_data(table_name, list_widget)

else:

QMessageBox.critical(self, "Ошибка", f"Не удалось удалить запись с ID


{record_id}.")

app.py

from PyQt5.QtWidgets import QApplication

from auth_window import AuthWindow

import sys

36
if __name__ == "__main__":

app = QApplication(sys.argv)

window = AuthWindow()

window.show()

sys.exit(app.exec())

auth_window.py

from PyQt5.QtWidgets import QMainWindow, QLabel, QLineEdit, QPushButton,


QVBoxLayout, QWidget, QMessageBox

from user_window import UserWindow

from admin_window import AdminWindow

from register_window import RegisterWindow

from database import Database

class AuthWindow(QMainWindow):

def __init__(self):

super().__init__()

self.setWindowTitle("Авторизация")

self.setGeometry(100, 100, 300, 200)

self.db = Database()

37
self.label_username = QLabel("Имя пользователя")

self.input_username = QLineEdit()

self.label_password = QLabel("Пароль")

self.input_password = QLineEdit()

self.input_password.setEchoMode(QLineEdit.EchoMode.Password)

self.button_login = QPushButton("Войти")

self.button_register = QPushButton("Регистрация")

layout = QVBoxLayout()

layout.addWidget(self.label_username)

layout.addWidget(self.input_username)

layout.addWidget(self.label_password)

layout.addWidget(self.input_password)

layout.addWidget(self.button_login)

layout.addWidget(self.button_register)

container = QWidget()

container.setLayout(layout)

self.setCentralWidget(container)

self.button_login.clicked.connect(self.login)

self.button_register.clicked.connect(self.register)

38
def login(self):

username = self.input_username.text()

password = self.input_password.text()

user = self.db.login_user(username, password)

if user:

user_id, role = user["id"], user["ur_dost"]

if role == 0:

self.user_window = UserWindow(user_id)

self.user_window.show()

else:

self.admin_window = AdminWindow()

self.admin_window.show()

self.close()

else:

QMessageBox.warning(self, "Ошибка", "Неверное имя пользователя или


пароль.")

def register(self):

self.register_window = RegisterWindow()

self.register_window.show()

39
self.close()

database.py

import mysql.connector

class Database:

def __init__(self):

self.conn = mysql.connector.connect(

host="localhost",

user="root",

password="03082005",

database="avecs_portal"

self.cursor = self.conn.cursor(dictionary=True)

def login_user(self, username, password):

query = "SELECT id, ur_dost FROM users WHERE username = %s AND


passwrd = %s"

self.cursor.execute(query, (username, password))

return self.cursor.fetchone()

40
def register_user(self, username, password, fio, dob, phone, email, position):

query = """

INSERT INTO users (username, passwrd, fio, date_of_birth, phone_number,


email, positionn, created_at, ur_dost)

VALUES (%s, %s, %s, %s, %s, %s, %s, NOW(), 0)

"""

self.cursor.execute(query, (username, password, fio, dob, phone, email,


position))

self.conn.commit()

def get_user_data(self, user_id):

query = """

SELECT fio, date_of_birth, phone_number, email, positionn, vacation

FROM users WHERE id = %s

"""

self.cursor.execute(query, (user_id,))

return self.cursor.fetchone()

def update_user_data(self, user_id, fio, phone, email, position):

query = """

UPDATE users

SET fio = %s, phone_number = %s, email = %s, positionn = %s, updated_at =
NOW()

41
WHERE id = %s

"""

self.cursor.execute(query, (fio, phone, email, position, user_id))

self.conn.commit()

def get_table_data(self, table_name):

query = f"SELECT * FROM {table_name}"

self.cursor.execute(query)

return self.cursor.fetchall()

def insert_data(self, table_name, data):

placeholders = ", ".join(["%s"] * len(data))

columns = ", ".join(data.keys())

query = f"INSERT INTO {table_name} ({columns}) VALUES


({placeholders})"

self.cursor.execute(query, tuple(data.values()))

self.conn.commit()

def update_data(self, table_name, data, id_column, id_value):

set_clause = ", ".join([f"{key} = %s" for key in data.keys()])

query = f"UPDATE {table_name} SET {set_clause} WHERE {id_column} =


%s"

self.cursor.execute(query, tuple(data.values()) + (id_value,))

42
self.conn.commit()

def delete_data_by_id(self, table_name, record_id):

try:

query = f"DELETE FROM {table_name} WHERE id = %s"

self.cursor.execute(query, (record_id,))

self.conn.commit()

return True

except Exception as e:

print(f"Ошибка при удалении записи: {e}")

return False

edit_record_dialog.py

from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QLabel,


QDialogButtonBox, QMessageBox

class EditRecordDialog(QDialog):

def __init__(self, data, table_name, db, parent=None):

super().__init__(parent)

self.db = db

43
self.table_name = table_name

self.data = data

self.setWindowTitle("Редактировать запись")

self.form_layout = QFormLayout(self)

self.fields = {}

for column, value in data.items():

if column != "id":

label = QLabel(column.capitalize())

field = QLineEdit(str(value) if value is not None else "")

self.form_layout.addRow(label, field)

self.fields[column] = field

button_box = QDialogButtonBox(QDialogButtonBox.Ok |
QDialogButtonBox.Cancel)

button_box.accepted.connect(self.accept)

button_box.rejected.connect(self.reject)

self.form_layout.addRow(button_box)

def accept(self):

"""Обработчик кнопки "Ок" — сохраняем изменения."""

44
updated_data = {}

for column, field in self.fields.items():

value = field.text()

if value == "" or value.lower() == "none":

updated_data[column] = None

else:

updated_data[column] = value

try:

self.db.update_data(self.table_name, updated_data, "id", self.data['id'])

QMessageBox.information(self, "Успех", "Запись успешно изменена!")

self.close()

except Exception as e:

QMessageBox.critical(self, "Ошибка", f"Не удалось изменить запись: {e}")

self.reject()

register_window.py

from PyQt5.QtWidgets import QMainWindow, QLabel, QLineEdit, QPushButton,


QVBoxLayout, QWidget, QMessageBox

45
from database import Database

class RegisterWindow(QMainWindow):

def __init__(self):

super().__init__()

self.setWindowTitle("Регистрация")

self.setGeometry(100, 100, 400, 300)

self.db = Database()

self.label_username = QLabel("Имя пользователя")

self.input_username = QLineEdit()

self.label_password = QLabel("Пароль")

self.input_password = QLineEdit()

self.input_password.setEchoMode(QLineEdit.EchoMode.Password)

self.label_fio = QLabel("ФИО")

self.input_fio = QLineEdit()

self.label_dob = QLabel("Дата рождения (YYYY-MM-DD)")

self.input_dob = QLineEdit()

self.label_phone = QLabel("Номер телефона")

self.input_phone = QLineEdit()

self.label_email = QLabel("Email")

self.input_email = QLineEdit()

46
self.label_position = QLabel("Должность")

self.input_position = QLineEdit()

self.button_register = QPushButton("Зарегистрироваться")

self.button_back = QPushButton("Назад")

layout = QVBoxLayout()

layout.addWidget(self.label_username)

layout.addWidget(self.input_username)

layout.addWidget(self.label_password)

layout.addWidget(self.input_password)

layout.addWidget(self.label_fio)

layout.addWidget(self.input_fio)

layout.addWidget(self.label_dob)

layout.addWidget(self.input_dob)

layout.addWidget(self.label_phone)

layout.addWidget(self.input_phone)

layout.addWidget(self.label_email)

layout.addWidget(self.input_email)

layout.addWidget(self.label_position)

layout.addWidget(self.input_position)

layout.addWidget(self.button_register)

layout.addWidget(self.button_back)

47
container = QWidget()

container.setLayout(layout)

self.setCentralWidget(container)

self.button_register.clicked.connect(self.register_user)

self.button_back.clicked.connect(self.go_back)

def register_user(self):

username = self.input_username.text()

password = self.input_password.text()

fio = self.input_fio.text()

dob = self.input_dob.text()

phone = self.input_phone.text()

email = self.input_email.text()

position = self.input_position.text()

if not username or not password or not fio:

QMessageBox.warning(self, "Ошибка", "Пожалуйста, заполните все


обязательные поля.")

return

48
try:

self.db.register_user(username, password, fio, dob, phone, email, position)

QMessageBox.information(self, "Успех", "Регистрация прошла успешно!")

self.go_back()

except Exception as e:

QMessageBox.critical(self, "Ошибка", f"Не удалось зарегистрировать


пользователя: {e}")

def go_back(self):

from auth_window import AuthWindow

self.auth_window = AuthWindow()

self.auth_window.show()

self.close()

user_window.py

from PyQt5.QtWidgets import QMainWindow, QLabel, QLineEdit, QPushButton,


QVBoxLayout, QWidget

from database import Database

class UserWindow(QMainWindow):

def __init__(self, user_id):

super().__init__()

49
self.setWindowTitle("Профиль пользователя")

self.user_id = user_id

self.db = Database()

self.label_fio = QLabel("ФИО")

self.input_fio = QLineEdit()

self.label_phone = QLabel("Телефон")

self.input_phone = QLineEdit()

self.label_email = QLabel("Email")

self.input_email = QLineEdit()

self.label_position = QLabel("Должность")

self.input_position = QLineEdit()

self.button_save = QPushButton("Сохранить")

layout = QVBoxLayout()

layout.addWidget(self.label_fio)

layout.addWidget(self.input_fio)

layout.addWidget(self.label_phone)

layout.addWidget(self.input_phone)

layout.addWidget(self.label_email)

layout.addWidget(self.input_email)

layout.addWidget(self.label_position)

50
layout.addWidget(self.input_position)

layout.addWidget(self.button_save)

container = QWidget()

container.setLayout(layout)

self.setCentralWidget(container)

self.load_data()

self.button_save.clicked.connect(self.save_data)

def load_data(self):

data = self.db.get_user_data(self.user_id)

self.input_fio.setText(data["fio"])

self.input_phone.setText(data["phone_number"])

self.input_email.setText(data["email"])

self.input_position.setText(data["positionn"])

def save_data(self):

fio = self.input_fio.text()

phone = self.input_phone.text()

email = self.input_email.text()

51
position = self.input_position.text()

self.db.update_user_data(self.user_id, fio, phone, email, position)

52
53
54

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