аааа
аааа
аааа
ВВЕДЕНИЕ ................................................................................................................ 6
1 Постановка задачи................................................................................................... 7
2 Моделирование проектируемой системы........................................................... 10
3 Разработка функциональных требований........................................................... 12
4 Обоснование выбора средств реализации........................................................... 14
5 Структура программы........................................................................................... 16
6 Схемы алгоритмов................................................................................................. 17
7 Результаты выполнения программы.................................................................... 21
ЗАКЛЮЧЕНИЕ......................................................................................................... 24
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ............................................... 25
ПРИЛОЖЕНИЕ А.................................................................................................... 27
ВВЕДЕНИЕ
5
1 Постановка задачи
Предметная область — это часть реального мира, исследуемая в рамках конкретного проекта
и описываемая средствами информационной системы.
Администратор:
Сотрудник:
6
Для реализации проекта используются Python с микрофреймворком Flask для создания
серверной части, а также HTML и CSS для разработки клиентской стороны с удобным
графическим интерфейсом. Данные хранятся в базе данных, управляемой с
помощью MySQL.
7
2 Моделирование проектируемой системы
8
6. Построение модели данных и процессов
На этапе моделирования использовались диаграммы IDEF0 для описания процессов
взаимодействия с системой и диаграммы IDEF1X для построения модели данных.
Диаграммы процессов описывают последовательность действий пользователя,
начиная с входа в систему и заканчивая формированием отчетов. Диаграмма данных
включает таблицы, связи между ними и ограничения, обеспечивающие целостность
данных.
9
На рисунке 2.3 представлена декомпозиция IDEF0 системы по учету
сотрудников и отпусков.
10
3 Разработка функциональных требований
1. Для администратора:
o Возможность добавления, изменения и удаления записей о сотрудниках;
o Управление данными об отпусках сотрудников;
o Просмотр всех данных, хранящихся в системе, с возможностью поиска и
фильтрации.
2. Для сотрудников:
o Просмотр и обновление личных данных, включая ФИО, контактную
информацию и должность;
o Просмотр данных о своих отпусках.
3. Общие функции:
o Авторизация пользователей с разными уровнями доступа (администратор и
сотрудник);
o Валидация данных при вводе и их проверка на соответствие заданным
правилам;
o Уведомления о результатах операций (успех или ошибка).
Требования к надежности:
11
o Python 3.9+ с использованием фреймворка Flask для серверной части
и HTML, CSS для интерфейса;
o СУБД MySQL для хранения данных.
Требования к интерфейсу:
12
4 Обоснование выбора средств реализации
13
предоставляющие удобный интерфейс для пользователей.
Причины выбора HTML и CSS:
o HTML предоставляет все необходимые элементы для создания структуры веб-
страниц.
o CSS обеспечивает гибкость в стилизации интерфейса, позволяя создавать
привлекательные и интуитивно понятные страницы.
o Поддержка всех современных веб-браузеров и мобильных устройств, что
делает интерфейс доступным на разных платформах.
5. Среда разработки PyCharm.
PyCharm был использован как основная среда разработки благодаря удобным
инструментам для написания, отладки и тестирования кода.
Преимущества PyCharm:
o Подсветка синтаксиса и автодополнение, что ускоряет написание кода.
o Встроенные средства для отладки и тестирования, упрощающие процесс
устранения ошибок.
o Поддержка управления версиями (например, через Git), что облегчает
командную работу.
14
5 Структура программы
3. Диалоговые окна:
15
Такое разделение обеспечивает модульность программы, упрощая
поддержку, добавление новых функций и тестирование отдельных
компонентов.
16
6 Схемы алгоритмов
Начало
login()
register()
Конец
Начало
self.register_window =
RegisterWindow()
self.register_window.show()
self.close()
Конец
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()
Возврат
18
7 Результаты выполнения программы
19
Рисунок 7.2 – Ошибка при вводе логина и пароля
20
Если какое-либо из обязательных полей не заполнено, то возникает
сообщение о соответствующей ошибке, которое представлено на рисунке 7.4
21
Рисунок 7.5 – Панель администратора
22
При добавлении пользователя все данные должны быть заполнены. На
рисунке 7.7 изображен вывод ошибки при оставленных пустых полях.
23
Если нажать на кнопку изменения пользователя(или удаления), то будет
отображено сообщение о том, что нужно кого-то выбрать. Это представлено на
рисунке 7.9.
24
При авторизации под логином и паролем пользователя открывается
форма, которая представлена на рисунке 7.11.
25
ЗАКЛЮЧЕНИЕ
26
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
27
ПРИЛОЖЕНИЕ А
(обязательное)
Листинг программы
28
add_record_dialog.py
class AddRecordDialog(QDialog):
super().__init__(parent)
self.db = db
self.table_name = table_name
self.form_layout = QFormLayout(self)
self.fields = {}
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 = {}
value = field.text()
new_data[column] = None
else:
new_data[column] = value
try:
self.db.insert_data(self.table_name, new_data)
30
QMessageBox.information(self, "Успех", "Новый пользователь
добавлен!")
self.close()
except Exception as e:
self.reject()
admin_window.py
import ast
import re
31
class AdminWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Панель администратора")
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.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)
33
widget.setLayout(layout)
return widget
list_widget.clear()
try:
data = self.db.get_table_data(table_name)
list_widget.addItem(str(row))
except Exception as e:
dialog.exec_()
current_item = list_widget.currentItem()
if not current_item:
return
34
raw_data = current_item.text().strip()
try:
row_data = eval(raw_data)
except Exception as e:
print(f"Error: {e}")
return
dialog.exec_()
import re
current_item = list_widget.currentItem()
if not current_item:
return
raw_data = current_item.text().strip()
35
match = re.search(r"'id': (\d+)", raw_data) # Ищем id: <число> в строке
if match:
else:
return
# Удаляем запись по ID
if self.db.delete_data_by_id(table_name, record_id):
self.load_table_data(table_name, list_widget)
else:
app.py
import sys
36
if __name__ == "__main__":
app = QApplication(sys.argv)
window = AuthWindow()
window.show()
sys.exit(app.exec())
auth_window.py
class AuthWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Авторизация")
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()
if user:
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:
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)
return self.cursor.fetchone()
40
def register_user(self, username, password, fio, dob, phone, email, position):
query = """
"""
self.conn.commit()
query = """
"""
self.cursor.execute(query, (user_id,))
return self.cursor.fetchone()
query = """
UPDATE users
SET fio = %s, phone_number = %s, email = %s, positionn = %s, updated_at =
NOW()
41
WHERE id = %s
"""
self.conn.commit()
self.cursor.execute(query)
return self.cursor.fetchall()
self.cursor.execute(query, tuple(data.values()))
self.conn.commit()
42
self.conn.commit()
try:
self.cursor.execute(query, (record_id,))
self.conn.commit()
return True
except Exception as e:
return False
edit_record_dialog.py
class EditRecordDialog(QDialog):
super().__init__(parent)
self.db = db
43
self.table_name = table_name
self.data = data
self.setWindowTitle("Редактировать запись")
self.form_layout = QFormLayout(self)
self.fields = {}
if column != "id":
label = QLabel(column.capitalize())
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 = {}
value = field.text()
updated_data[column] = None
else:
updated_data[column] = value
try:
self.close()
except Exception as e:
self.reject()
register_window.py
45
from database import Database
class RegisterWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Регистрация")
self.db = Database()
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.input_dob = QLineEdit()
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()
return
48
try:
self.go_back()
except Exception as e:
def go_back(self):
self.auth_window = AuthWindow()
self.auth_window.show()
self.close()
user_window.py
class UserWindow(QMainWindow):
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()
52
53
54