Курсовой проект Разработка тикет системы для ИТ отдела. Курсач. Министерство цифрового развития
![]()
|
ЗАКЛЮЧЕНИЕ Результатом выполнения дипломного проекта на тему «Разработка тикет системы для ИТ отдела» была разработана программа, предназначенная для работы ИТ отдела с заявками и обращениями пользователей. В ходе моделирования программного продукта были построены следующие диаграммы: Три диаграммы IDEF0 Одна диаграмма USECASE Четыре диаграммы деятельности Четыре диаграммы последовательности В процессе проектирования и разработки были выполнены следующие задачи: разработана одна база данных SQL, содержащая две таблицы: «Пользователь» и «Заявка». разработано приложение, позволяющее: Оставлять заявки в техническую поддержку; Просматривать заявки; Передавать заявки между различными профильными группами технической поддержки; Закрывать заявки и вести их историю; Просматривать статус своей заявки; Просматривать решение по своей заявке; Вести протокол заявки реализован доступ приложения к разработанным базам. Проведенное тестирование показало, что функционал программного продукта работает корректно, в соответствии с установленными требованиями. Графический интерфейс интуитивно понятен, не требует длительного времени на освоение, работает корректно. В процессе выполнения выпускной квалификационной работы был проведен расчет метрик стилистики и понятности программы, разработана следующая документация: руководство пользователя; руководство администратора Таким образом, разработанный программный продукт дает возможность полноценно внедрить его в небольшом офисе или компании для упрощения работы ИТ отдела посредством регистрации обращений пользователей с помощью тикетов. ИСПОЛЬЗОВАННЫЕ ИСТОЧНИКИ 1. Введение в SQL. Грабер М. – М.: Лори, 2018 – 378 с. 2. Инновации SQL Server 2019. Уорд. Б. – М.: ДМК Пресс, 2020 – 408 с. 3. Изучаем C#. Стиллмен Э. – М.: Питер, 2020 – 816 с. 4. Microsoft Docs Руководство по языку С# https://docs.microsoft.com/ru-ru/dotnet/csharp 5. Metanit.com Полное руководство по языку программирования С# 9.0 и платформе .NET5 https://metanit.com/sharp/tutorial/ 6. SQL Задачи и решения. Учебник. Сергей Моисеенко http://www.sql-tutorial.ru/ru/content.html 7. Разработка обслуживаемых программ на языке C#, Джуст В. – М.: ДМК Пресс, 2017 – 192 с. 8. Microsoft Visual C#. Подробное руководство. 8-е изд. Шарп Д. – М.: Питер, 2017 – 848 с. 9. Руководство по SQL (полная версия) – https://proselyte.net/tutorials/sql/ 10. Интерактивный учебник по SQL – https://sql-academy.org/ru/guide 11. Статья «Учебник по языку SQL (DDL, DML) на примере диалекта MS SQL Server. Часть первая» – https://habr.com/ru/post/255361/ 12. Статья «Учебник по языку SQL (DDL, DML) на примере диалекта MS SQL Server. Часть первая» – https://habr.com/ru/post/255361/ 13. Основа WPF – https://professorweb.ru/my/WPF/base_WPF/level1/base_WPF_index.php (07.04.2021) 14. Элементы управления WPF – https://professorweb.ru/my/WPF/UI_WPF/level6/UI_WPF_index.php (07.04.2021) ПРИЛОЖЕНИЕ 1 Файл конфигурации App.config providerName="System.Data.SqlClient" /> Файл окна авторизации LoginWindow.xaml.cs namespace WpfApp1 /// Логика взаимодействия для LoginWindow.xaml { public partial class LoginWindow : Window { public LoginWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) //обработка нажатия кнопки "Вход в систему" { if (LoginTextBox.Text == "") //Не введён логин { MessageBox.Show("Введите логин"); return; } if (PasswordTextBox.Password == "") //Не введён пароль { MessageBox.Show("Введите пароль"); return; } MainWindow.executeSQL("SELECT [Уникальный_ключ],[Фамилия],[Имя],[Отдел],[Должность],[Логин],[Пароль] FROM [TicketSystem].[dbo].[Пользователь]"); //Указываем таблицу и данные для извлечения из БД for(int i = 0; i < MainWindow.DT.Rows.Count; i++) { List Console.WriteLine(Values[0]); Console.WriteLine(Values[1]); Console.WriteLine(Values[2]); Console.WriteLine(Values[3]); Console.WriteLine(Values[4]); if (Values[5] == LoginTextBox.Text && Values[6] == PasswordTextBox.Password) //Сопоставляем данные из полей "Логин" и "Пароль" с информацией из таблицы БД { MainWindow MW = new MainWindow(); MW.AccountData[0] = Values[0]; MW.AccountData[1] = Values[1]; MW.AccountData[2] = Values[2]; MW.AccountData[3] = Values[3]; MW.AccountData[4] = Values[4]; Console.WriteLine(MW.AccountData[0] + MW.AccountData[1]+MW.AccountData[3]+MW.AccountData[4]); MW.setAccountData(); MW.Show(); Close(); return; //возврат значения } } MessageBox.Show("Неверный логин или пароль!"); //Всплывающее окно LoginTextBox.Text = ""; PasswordTextBox.Password = ""; } private void Button_Click_1(object sender, RoutedEventArgs e) //Обработчик нажатия кнопки "Создать заявку" { RequestWindow RW = new RequestWindow(); //открывает новое окно "Создание заявки" RW.Show(); } private void Button_Click_2(object sender, RoutedEventArgs e) //Обработчик кнопки "Проверить заявку" { if (RequestCheck.Text == "") return; //возврат значения try { MainWindow.executeSQL("SELECT [Статус],[Решение] FROM [TicketSystem].[dbo].[Заявка] WHERE([Уникальный_ключ]=" + RequestCheck.Text + ")"); //поиск заявки в БД } catch //Исключение - ничего не возвращается { return; } if (MainWindow.DT.Rows.Count == 0) //На случай указания не верного номера заявки { MessageBox.Show("Заявки с таким номером не существует!"); //всплывающее окно return; } RStatus.Content = "Статус заявки: " +MainWindow.getSQLValue(0,"Статус"); //вывод на экран статуса RDT.Text = "Решение по данной заявке: "+Environment.NewLine+MainWindow.getSQLValue(0, "Решение"); //вывод на экран решения } } } Файл рабочего окна MainWindow.xaml.cs namespace WpfApp1 /// Логика взаимодействия для MainWindow.xaml { public partial class MainWindow : Window { public static string SQL; public static SqlDataReader SqlReader; public static SqlConnection SQLC = new SqlConnection(); public static SqlCommand cmd = new SqlCommand("", SQLC); public static DataTable DT = new DataTable(); public static SqlDataAdapter Adapter = new SqlDataAdapter(); public static string ServerString = GetConnectionString(); public string[] AccountData = {"","","","",""}; public static DataTable LocalDT = new DataTable(); public MainWindow() { InitializeComponent(); updateRequestView(); } public void setAccountData() //извлекаем данные авторизованного пользователя ФИО, должность, отдел { LabelFIO.Content = "ФИО: " + AccountData[1] + " " + AccountData[2]; LabelRole.Content = "Должность: " + AccountData[4]; LabelWorkGroup.Content = "Отдел: " + AccountData[3]; } private void Window_Loaded(object Sender,RoutedEventArgs e) { } public static String GetConnectionString() //Извлекаем файла конфигурации данные для подключения к БД { return ConfigurationManager.ConnectionStrings["conString"].ToString(); } public static void openConnection() //Подключаемся к серверу согласно извлеченным данным { try { if(SQLC.State == ConnectionState.Closed) { SQLC.ConnectionString = GetConnectionString(); SQLC.Open(); } } catch (Exception ex) //Исключение - если не подключился { MessageBox.Show("SQL сервер не найден!"); //всплывающее окно return; } } public static void closeConnection() //отключаемся от сервера { try { if (SQLC.State == ConnectionState.Open) { SQLC.Close(); } } catch (Exception ex) //исключение если не отключился { MessageBox.Show("Невозможно закрыть сервер!"); } } public static void executeSQL(string Code) //Запись данных в буфер { MainWindow.openConnection(); //подключение MainWindow.DT.Clear(); MainWindow.SQL = Code; MainWindow.cmd.CommandType = System.Data.CommandType.Text; MainWindow.cmd.CommandText = MainWindow.SQL; MainWindow.Adapter.SelectCommand = MainWindow.cmd; MainWindow.Adapter.Fill(MainWindow.DT); MainWindow.closeConnection(); //закрытие подключения } public static void executeSQL(string Code, DataTable LocalDT) // { MainWindow.openConnection(); //подключение LocalDT.Clear(); //очистка локальной таблицы MainWindow.SQL = Code; MainWindow.cmd.CommandType = System.Data.CommandType.Text; MainWindow.cmd.CommandText = MainWindow.SQL; MainWindow.Adapter.SelectCommand = MainWindow.cmd; MainWindow.Adapter.Fill(LocalDT); //заполнение локальной таблицы данными MainWindow.closeConnection(); //закрытие подключения } public static string getStringFromSql(string str) //получение индекса по строке { int SIndex = str.IndexOf(' '); if (SIndex == -1) SIndex = str.Length; return str.Substring(0, SIndex); //возвращает индекс } public static int getIndexColumn(string name) //возвращает индекс столбца { for(int i = 0; i < DT.Columns.Count; i++) { if (DT.Columns[i].ColumnName == name) { return i; //индекс } } return 0; } public static int getIndexColumn(string name,DataTable SDT) //возвращает индекс столбца { for (int i = 0; i < SDT.Columns.Count; i++) { if (SDT.Columns[i].ColumnName == name) { return i; //индекс } } return 0; } public static string getSQLValue(int index,string name) //возвращает значения { return DT.Rows[index].ItemArray[getIndexColumn(name)].ToString(); } public static List { List for (int i = 0; i < SDT.Columns.Count; i++) //столбцы { for (int j = 0; j < Values.Length; j++) //строки { if (SDT.Columns[i].ColumnName == Values[j]) { RValues.Add(SDT.Rows[Index].ItemArray[i].ToString()); } } } return RValues; //вернутые значения =) } public void updateRequestView() //отображение в виде таблицы по умолчанию { LocalDT.Clear(); LocalDT.Columns.Clear(); executeSQL("SELECT [Уникальный_ключ],[Тип_заявки],[Рабочая_группа],[Исполнитель],[Статус] FROM [TicketSystem].[dbo].[Заявка] WHERE([Статус]<>'Закрыта')", LocalDT); //отображение только закрытых заявок loadToLocalData(); } public void loadToLocalData() //Изменение имени столбцов { RequestCount.Text = LocalDT.Rows.Count.ToString(); LocalDT.Columns[getIndexColumn("Уникальный_ключ", LocalDT)].ColumnName = "ID"; //Переименование столбца LocalDT.Columns[getIndexColumn("Тип_заявки", LocalDT)].ColumnName = "Тип заявки"; //Переименование столбца LocalDT.Columns[getIndexColumn("Рабочая_группа", LocalDT)].ColumnName = "Рабочая группа"; //Переименование столбца RequestDataView.ItemsSource = LocalDT.DefaultView; } private void CreateTick_Click(object sender, RoutedEventArgs e) //Обработчк нажатия кнопки "Создать заявку" { RequestWindow RW = new RequestWindow(); //открывает новое окно "Создание заявки" RW.Show(); RW.adminSend((string)LabelFIO.Content.ToString().Substring(4)); } private void FindButton_Click(object sender, RoutedEventArgs e) //Обработчик нажатия кнопки "Поиск" { if (TextBoxNumberTicket.Text == "") return; //возврат значения LocalDT.Clear(); LocalDT.Columns.Clear(); try { executeSQL("SELECT [Уникальный_ключ],[Тип_заявки],[Рабочая_группа],[Исполнитель],[Статус] FROM [TicketSystem].[dbo].[Заявка] WHERE([Уникальный_ключ]=" + TextBoxNumberTicket.Text + ")", LocalDT); //отображение заявок с сортировкой по уникальному номеру. } catch { return; } loadToLocalData(); //Изменение имени столбцов } private void ClosedTicks_Click(object sender, RoutedEventArgs e) //Обработчик нажатия кнопки "Закрытые заявки" { LocalDT.Clear(); LocalDT.Columns.Clear(); executeSQL("SELECT [Уникальный_ключ],[Тип_заявки],[Рабочая_группа],[Исполнитель],[Статус] FROM [TicketSystem].[dbo].[Заявка] WHERE([Статус]='Закрыта')", LocalDT); //выбор только заявок со статусом "закрыта" loadToLocalData(); } private void AllTicks_Click(object sender, RoutedEventArgs e) //Обработчик нажатия кнопки "Все заявки" { updateRequestView(); //Отображение таблицы с заявками по умолчанию, без фильтров. } private void MyGroupTicks_Click(object sender, RoutedEventArgs e) //Обработчик нажатия кнопки "Заявки моей группы" { LocalDT.Clear(); LocalDT.Columns.Clear(); executeSQL("SELECT [Уникальный_ключ],[Тип_заявки],[Рабочая_группа],[Исполнитель],[Статус] FROM [TicketSystem].[dbo].[Заявка] WHERE([Рабочая_группа]='"+AccountData[3]+"')", LocalDT); //Отображение заявок в которых рабочая группа текущего пользователя является ответственной. loadToLocalData(); //Изменение имени столбцов } private void RequestDataView_SelectionChanged(object sender, SelectionChangedEventArgs e) { } private void RequestDataView_DoubleClick(object sender, MouseButtonEventArgs e) //обработчик двойного клика по заголовку заявки в таблице { if (RequestDataView.SelectedItem == null) return; DataRowView DRV = (DataRowView)RequestDataView.SelectedItem; RequestProtocolWindow RPW = new RequestProtocolWindow(); //Открывает заявку в окне просмотра заявки RPW.sendRequest(DRV["ID"].ToString()); RPW.Show(); } } } Файл окна создания заявки RequestWindow.xaml.cs namespace WpfApp1 /// Логика взаимодействия для RequestWindow.xaml { public partial class RequestWindow : Window { public RequestWindow() { InitializeComponent(); //инициализация компонента } public void adminSend(string FIO) { TB_FIO.Text = FIO; } private void Button_Click(object sender, RoutedEventArgs e) //обработчик нажатия кнопки "создать заявку" { if(TB_FIO.Text=="" || TB_Email.Text == "" || TB_Phone.Text == "") { MessageBox.Show("Введите свои данные полностью"); //Всплывающее окно return; } if (ComboBoxRequestType.Text == "") { MessageBox.Show("Выберите тип заявки"); //Всплывающее окно return; } string RBody = new TextRange(RequestBody.Document.ContentStart, RequestBody.Document.ContentEnd).Text; if (RBody == "") { MessageBox.Show("Опишите проблему перед тем как отправить"); //Всплывающее окно return; } try { MainWindow.executeSQL("INSERT INTO [TicketSystem].[dbo].[Заявка] ([Ваше_ФИО],[Рабочая_почта],[Контактный_телефон],[Тип_заявки],[Описание_заявки],[Статус],[Рабочая_группа],[Исполнитель]) VALUES('" + TB_FIO.Text + "', '" + TB_Email.Text + "','" + TB_Phone.Text + "','" + ComboBoxRequestType.Text + "','" + RBody + "','Зарегистрирована','Поддержка 1-я линия','Не назначен'); "); } catch { |