Курсовой проект Разработка тикет системы для ИТ отдела. Курсач. Министерство цифрового развития
Скачать 0.8 Mb.
|
3.2 Разработка программных модулей Для начала необходимо обеспечить подключение к разработанным базам данных. Метод getConnectionString() получает адрес SQL-сервера, к которому будет подключаться. public static String GetConnectionString() //Извлекаем файла конфигурации данные для подключения к БД { return ConfigurationManager.ConnectionStrings["conString"].ToString(); } Данные адреса хранятся в в config файле в строке conString: providerName="System.Data.SqlClient" /> Метод openConnection() реализует подключение к БД. В случае неудачи выдает исключение и всплывающее сообщение «Невозможно открыть SQL сервер»: public static void openConnection() //Подключаемся к серверу согласно извлеченным данным { try { if(SQLC.State == ConnectionState.Closed) { SQLC.ConnectionString = GetConnectionString(); SQLC.Open(); } } catch (Exception ex) //Исключение - если не подключился { MessageBox.Show("SQL сервер не найден!"); //всплывающее окно return; } } Для закрытия сессии подключения к базе данных используется метод closeConnection(): public static void closeConnection() //отключаемся от сервера { try { if (SQLC.State == ConnectionState.Open) { SQLC.Close(); } } catch (Exception ex) //исключение если не отключился { MessageBox.Show("Невозможно закрыть сервер!"); } } В случае неудачи выдает исключение – ничего не возвращает. Метод executeSQL(string Code) обеспечивает выполнение SQL-команд. На вход подается строка, которая хранит инструкцию. В случае удачного выполнения, полученные данные загружаются в таблицу DT и могут быть дальше использованы: public static void executeSQL(string Code) //выполнение команд { openConnection(); //подключение DT.Clear(); DT.Columns.Clear(); SQL = Code; //выполнение кода Cmd.CommandType = System.Data.CommandType.Text; Cmd.CommandText = SQL; Adapter.SelectCommand = Cmd; //загрузка данных с БД Adapter.Fill(DT); closeConnection(); //закрытие подключения } В случае неудачи выдает исключение – ничего не возвращает. Метод executeSQL(string Code) обеспечивает выполнение SQL-команд. На вход подается строка, которая хранит инструкцию. В случае удачного выполнения, полученные данные загружаются в таблицу DT и могут быть дальше использованы: public static void executeSQL(string Code) //выполнение команд { openConnection(); //подключение DT.Clear(); DT.Columns.Clear(); SQL = Code; //выполнение кода Cmd.CommandType = System.Data.CommandType.Text; Cmd.CommandText = SQL; Adapter.SelectCommand = Cmd; //загрузка данных с БД Adapter.Fill(DT); closeConnection(); //закрытие подключения } Метод getIndexColumn(string name) возвращает индекс столбца, который нумеруется аргументом. Он необходим для правильного получения данных из конкретного столбца по его имени, такой метод не кэширует пару индекс-имя столбца: public static int getIndexColumn(string name, DataTable LocalDT) //возвращает индекс столбца { for (int i = 0; i < LocalDT.Columns.Count; i++) { if (LocalDT.Columns[i].ColumnName == name) { return i; //индекс } } return 0; } getDynamicSqlValues(int Index,string[] Values,DataTable SDT) – общий метод для возврата значений в виде списка, возвращает все требуемые значения. Здесь необходимо указать таблицу (SDT) для хранения данных. Такой метод не кэширует пару индекс-имя столбца: public static List Values, DataTable SDT) //возврат значений в виде списка { 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; //возвращение значения } Начальная страница обеспечивает вход в приложение после ввода логина и пароля, создание заявки без авторизации и узнать статус заявки по её номеру. private void Button_Click(object sender, RoutedEventArgs e) //обработка нажатия кнопки "Вход в систему" { if (LoginTextBox.Text == "") //Не введён логин { MessageBox.Show("Введите логин"); return; } if (PasswordTextBox.Password == "") //Не введён пароль { MessageBox.Show("Введите пароль"); return; } 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; } Здесь при отсутствии логина, пароля появляется сообщение с просьбой ввести логин или пароль, а в случае ввода не верных учетных данных, будет вызвано окно с сообщением о не корректности введенных данных.. В обратном случае сохраняется индекс БД и происходит выгрузка данных из таблицы «Пользователь». Далее происходит проверка логина и пароля с данными, после чего авторизация завершается и пользователь начинает работу с приложением. Фамилия, имя и отчество пользователя, а так же должность и рабочая группа сохраняются в DBConnection.CurrentUser для отображения в заголовке рабочего окна. Данные извлекаются из БД методом «setAccountData». public void setAccountData() { LabelFIO.Content = "ФИО: " + AccountData[1] + " " + AccountData[2]; LabelRole.Content = "Должность: " + AccountData[4]; LabelWorkGroup.Content = "Отдел: " + AccountData[3]; } Подключение к БД осуществляется с помощью методов: String GetConectionString – для извлечения адреса и данных авторизации приложения в БД из файла конфигурации App.config; openConnection для подключения к БД. public static String GetConnectionString() { return ConfigurationManager.ConnectionStrings["conString"].ToString(); } public static void openConnection() { try { if(SQLC.State == ConnectionState.Closed) { SQLC.ConnectionString = GetConnectionString(); SQLC.Open(); } } Страница «Рабочее окно» отображает информацию из таблицы «Заявки» и умеет сортировать заявки по номеру, ответственной группе, типу заявки. 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; } Кнопки в рабочем окне позволят открывать необходимые страницы с помощью событий: CreateTick_Click (Создать заявку), ClosedTicks_Click (Закрытые заявки), AllTicks_Click (Все заявки), MyGroupTicks_Click (Заявки моей группы). Пример использования: private void CreateTick_Click(object sender, RoutedEventArgs e) { RequestWindow RW = new RequestWindow(); RW.Show(); RW.adminSend((string)LabelFIO.Content.ToString().Substring(4)); } 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(); } Так же в рабочем окне имеется возможность открыть окно для работы с заявкой с помощью двойного клика по заголовку в списке заявок с помощью методов: RequestDataView_SelectionChanged и RequestDataView_DoubleClick. Пример: 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(); } При открытии заявки двойным кликом открывается отдельно окно в которое подгружаются все данные связанные с данной заявкой. Поиск выполняется по уникальному id заявки с помощью метода SendRequest: public void sendRequest(string _RID) //Отображение данных по заявке { MainWindow.executeSQL("SELECT [Уникальный_ключ],[Ваше_ФИО],[Рабочая_почта],[Контактный_телефон],[Тип_заявки],[Описание_заявки],[Статус],[Исполнитель],[Протокол],[Решение],[Рабочая_группа] FROM [TicketSystem].[dbo].[Заявка] WHERE([Уникальный_ключ]=" + _RID + ")"); List RID.Text = MainWindow.getSQLValue(0, "Уникальный_ключ"); //Отображение данных в соответствующем окне RUser.Text = MainWindow.getSQLValue(0, "Ваше_ФИО"); REmail.Text = MainWindow.getSQLValue(0, "Рабочая_почта"); RPhone.Text = MainWindow.getSQLValue(0, "Контактный_телефон"); //Отображение данных в соответствующем окне RType.Text = MainWindow.getSQLValue(0, "Тип_заявки"); RBody.Text = MainWindow.getSQLValue(0, "Описание_заявки"); RProtocol.AppendText(MainWindow.getSQLValue(0, "Протокол")); Rdecision.AppendText(MainWindow.getSQLValue(0, "Решение")); //Отображение данных в соответствующем окне string Status = MainWindow.getSQLValue(0, "Статус"); //Отобразить статус из списка if (Status == "Назначена") RStatus.SelectedIndex = 0; if (Status == "На уточнении") RStatus.SelectedIndex = 1; if (Status == "В работе") RStatus.SelectedIndex = 2; if (Status == "Закрыта") RStatus.SelectedIndex = 3; string sRWorkGroup = MainWindow.getSQLValue(0, "Рабочая_группа"); //Отобразить for(int i = 0; i { ComboBoxItem iItem = (ComboBoxItem)RWorkGroup.Items[i]; //Выпадающий список if (sRWorkGroup == (string)iItem.Content) { RWorkGroup.SelectedIndex = i; } } RExecuter.Text = MainWindow.getSQLValue(0, "Исполнитель"); } В открытой заявке появляется возможность заполнить совершенно новые поля «Протокол» и «Решение для пользователя», с помощью метода: Button_Click private void Button_Click(object sender, RoutedEventArgs e) { string Protocol = new TextRange(RProtocol.Document.ContentStart, RProtocol.Document.ContentEnd).Text; //Ввод текста в поле "протокол" string Decision = new TextRange(Rdecision.Document.ContentStart, Rdecision.Document.ContentEnd).Text; //Ввод текста в поле "Решение" try { MainWindow.executeSQL("UPDATE [TicketSystem].[dbo].[Заявка] SET [Ваше_ФИО]='" + RUser.Text + "',[Рабочая_почта]='" + REmail.Text + "',[Контактный_телефон]='" + RPhone.Text + "',[Тип_заявки]='" + RType.Text + "',[Описание_заявки]='" + RBody.Text + "',[Статус]='" + RStatus.Text + "',[Исполнитель]='" + RExecuter.Text + "',[Протокол]='" + Protocol + "',[Решение]='" + Decision + "',[Рабочая_группа]='" + RWorkGroup.Text + "' WHERE([Уникальный_ключ]=" + RID.Text + ")"); } catch //исключение { MessageBox.Show("Ошибка введеных данных"); //Всплывающее окно return; } } Есть возможность выполнить поиск заявки с помощью метода FindButton_Click: 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; } Описание методов – обработчиков событий этого окна представлено в таблице (табл. 3.1): Таблица 3.1 Обработчики событий рабочего окна
Окно создания заявки позволяет создать и отправить заявку в БД с помощью метода Button Click. В случае не заполнения обязательного пункта, появится соответствующее всплывающее окно. 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 { MessageBox.Show("Проверьте правильность введеных данных"); //Вслывающее окно return; } try { MainWindow.executeSQL("SELECT [Уникальный_ключ] FROM [TicketSystem].[dbo].[Заявка] WHERE([Ваше_ФИО]='" + TB_FIO.Text + "' AND [Рабочая_почта]='" + TB_Email.Text + "' AND [Контактный_телефон]='" + TB_Phone.Text + "' AND [Тип_заявки]='" + ComboBoxRequestType.Text + "' AND [Описание_заявки]='" + RBody + "')"); } catch { MessageBox.Show("Проверьте правильность введеных данных"); //Всплывающее окно return; } MessageBox.Show("Заявка под номером "+ MainWindow.getSQLValue(0, "Уникальный_ключ") +" отправлена"); //Всплывающее окно Close(); } } } В окне просмотра заявки есть возможность назначить рабочую группу и выбрать ответственного за данную заявку специалиста из выпадающего списка с помощью методов: RExecuters_SelectionChanged и RWorkGroup_SelectionChanged: private void RWorkGroup_SelectionChanged(object sender, SelectionChangedEventArgs e) //Выбрать ответственную группу { ComboBoxItem iItem = (ComboBoxItem)RWorkGroup.SelectedItem; //Выпадающий список MainWindow.executeSQL("SELECT [Уникальный_ключ],[Фамилия],[Имя],[Отдел],[Должность],[Логин],[Пароль] FROM [TicketSystem].[dbo].[Пользователь] WHERE([Отдел]='" + iItem.Content + "')"); Console.WriteLine("SELECT [Уникальный_ключ],[Фамилия],[Имя],[Отдел],[Должность],[Логин],[Пароль] FROM [TicketSystem].[dbo].[Пользователь] WHERE([Отдел]='" + iItem.Content + "')"); if (MainWindow.DT.Rows.Count == 0) return; //Возврат данных RExecuters.Items.Clear(); for (int i = 0; i < MainWindow.DT.Rows.Count; i++) { string E = MainWindow.getSQLValue(i, "Фамилия") + " " + MainWindow.getSQLValue(i, "Имя"); //Отображение ответственного в выпадающем списке RExecuters.Items.Add(E); } } Следующий шаг после разработки программного продукта – его тестирование. |