using Npgsql; using System; using System.Data; using System.Windows; using System.Windows.Controls; namespace WpfApp1 { public partial class DriversWindow : Window { private const string Conn = "Host=80.250.189.52;Port=5432;Database=dbwork;Username=kotov_aa;Password=0$s%MB3&F6#"; public DriversWindow() { InitializeComponent(); ApplyPermissions(); LoadDrivers(); } private void ApplyPermissions() { string role = AppSession.Role; bool canEdit = role == "admin" || role == "dispatcher"; bool canDelete = role == "admin"; // Безопасный перебор кнопок var grid = Content as Grid; if (grid == null || grid.Children.Count < 3) return; var panel = grid.Children[2] as StackPanel; if (panel == null) return; foreach (var child in panel.Children) { if (child is Button btn) { string content = btn.Content?.ToString() ?? ""; if (content.Contains("Добавить") || content.Contains("Изменить")) btn.IsEnabled = canEdit; if (content.Contains("Удалить")) btn.IsEnabled = canDelete; } } } private void LoadDrivers() { try { string sql = "SELECT * FROM Drivers ORDER BY driverid"; using var conn = new NpgsqlConnection(Conn); conn.Open(); var adapter = new NpgsqlDataAdapter(sql, conn); DataTable dt = new DataTable(); adapter.Fill(dt); dgDrivers.ItemsSource = dt.DefaultView; } catch (Exception ex) { MessageBox.Show("Ошибка загрузки: " + ex.Message); } } private void BtnRefresh_Click(object sender, RoutedEventArgs e) => LoadDrivers(); private void BtnAdd_Click(object sender, RoutedEventArgs e) { if (AppSession.Role == "driver") { MessageBox.Show("Нет прав"); return; } var dlg = new EditDriverWindow(); dlg.Title = "Добавление водителя"; if (dlg.ShowDialog() == true) { try { // ✅ ПАРАМЕТРИЗОВАННЫЙ ЗАПРОС (защита от SQL-инъекций) string sql = "INSERT INTO Drivers (lastname, fullname, tabnumber) " + "VALUES (@lastname, @fullname, @tabnumber)"; using var conn = new NpgsqlConnection(Conn); conn.Open(); using var cmd = new NpgsqlCommand(sql, conn); cmd.Parameters.AddWithValue("@lastname", dlg.LastName ?? ""); cmd.Parameters.AddWithValue("@fullname", dlg.FullName ?? ""); cmd.Parameters.AddWithValue("@tabnumber", dlg.TabNumber ?? ""); int affected = cmd.ExecuteNonQuery(); if (affected > 0) { LoadDrivers(); MessageBox.Show("Водитель успешно добавлен", "Успех", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (PostgresException pgEx) { // Специальная обработка ошибок PostgreSQL string errorMsg = "Ошибка базы данных:\n"; if (pgEx.SqlState == "23505") errorMsg += "Табельный номер уже существует!"; else if (pgEx.SqlState == "23503") errorMsg += "Нарушение связей в базе данных."; else if (pgEx.SqlState == "42P01") errorMsg += "Таблица не найдена. Проверьте структуру БД."; else errorMsg += pgEx.MessageText + "\nКод: " + pgEx.SqlState; MessageBox.Show(errorMsg, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception ex) { MessageBox.Show("Ошибка: " + ex.Message + "\n\n" + ex.StackTrace, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error); } } } private void BtnEdit_Click(object sender, RoutedEventArgs e) { if (AppSession.Role == "driver") { MessageBox.Show("Нет прав"); return; } if (dgDrivers.SelectedItem == null) { MessageBox.Show("Выберите запись"); return; } var row = (DataRowView)dgDrivers.SelectedItem; var dlg = new EditDriverWindow(); dlg.Title = "Изменение водителя"; dlg.DriverId = Convert.ToInt32(row["driverid"]); dlg.LastName = row["lastname"].ToString(); dlg.FullName = row["fullname"].ToString(); dlg.TabNumber = row["tabnumber"].ToString(); if (dlg.ShowDialog() == true) { try { // ✅ ПАРАМЕТРИЗОВАННЫЙ ЗАПРОС string sql = "UPDATE Drivers SET lastname=@lastname, " + "fullname=@fullname, tabnumber=@tabnumber " + "WHERE driverid=@driverid"; using var conn = new NpgsqlConnection(Conn); conn.Open(); using var cmd = new NpgsqlCommand(sql, conn); cmd.Parameters.AddWithValue("@lastname", dlg.LastName ?? ""); cmd.Parameters.AddWithValue("@fullname", dlg.FullName ?? ""); cmd.Parameters.AddWithValue("@tabnumber", dlg.TabNumber ?? ""); cmd.Parameters.AddWithValue("@driverid", dlg.DriverId); cmd.ExecuteNonQuery(); LoadDrivers(); MessageBox.Show("Данные обновлены", "Успех", MessageBoxButton.OK, MessageBoxImage.Information); } catch (PostgresException pgEx) { string errorMsg = "Ошибка базы данных:\n"; if (pgEx.SqlState == "23505") errorMsg += "Табельный номер уже существует!"; else errorMsg += pgEx.MessageText; MessageBox.Show(errorMsg, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception ex) { MessageBox.Show("Ошибка: " + ex.Message); } } } private void BtnDelete_Click(object sender, RoutedEventArgs e) { if (AppSession.Role != "admin") { MessageBox.Show("Только администратор может удалять"); return; } if (dgDrivers.SelectedItem == null) { MessageBox.Show("Выберите запись"); return; } var row = (DataRowView)dgDrivers.SelectedItem; int id = Convert.ToInt32(row["driverid"]); if (MessageBox.Show("Удалить запись?", "Подтверждение", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { try { string sql = "DELETE FROM Drivers WHERE driverid = @id"; using var conn = new NpgsqlConnection(Conn); conn.Open(); using var cmd = new NpgsqlCommand(sql, conn); cmd.Parameters.AddWithValue("@id", id); cmd.ExecuteNonQuery(); LoadDrivers(); MessageBox.Show("Запись удалена", "Успех", MessageBoxButton.OK, MessageBoxImage.Information); } catch (PostgresException pgEx) { string errorMsg = "Ошибка базы данных:\n"; if (pgEx.SqlState == "23503") errorMsg += "Нельзя удалить: водитель закреплён за машиной!"; else errorMsg += pgEx.MessageText; MessageBox.Show(errorMsg, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception ex) { MessageBox.Show("Ошибка: " + ex.Message); } } } } }