DriversWindow.xaml.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using Npgsql;
  2. using System;
  3. using System.Data;
  4. using System.Windows;
  5. using System.Windows.Controls;
  6. namespace WpfApp1
  7. {
  8. public partial class DriversWindow : Window
  9. {
  10. private const string Conn = "Host=80.250.189.52;Port=5432;Database=dbwork;Username=kotov_aa;Password=0$s%MB3&F6#";
  11. public DriversWindow()
  12. {
  13. InitializeComponent();
  14. ApplyPermissions();
  15. LoadDrivers();
  16. }
  17. private void ApplyPermissions()
  18. {
  19. string role = AppSession.Role;
  20. bool canEdit = role == "admin" || role == "dispatcher";
  21. bool canDelete = role == "admin";
  22. // Безопасный перебор кнопок
  23. var grid = Content as Grid;
  24. if (grid == null || grid.Children.Count < 3) return;
  25. var panel = grid.Children[2] as StackPanel;
  26. if (panel == null) return;
  27. foreach (var child in panel.Children)
  28. {
  29. if (child is Button btn)
  30. {
  31. string content = btn.Content?.ToString() ?? "";
  32. if (content.Contains("Добавить") || content.Contains("Изменить"))
  33. btn.IsEnabled = canEdit;
  34. if (content.Contains("Удалить"))
  35. btn.IsEnabled = canDelete;
  36. }
  37. }
  38. }
  39. private void LoadDrivers()
  40. {
  41. try
  42. {
  43. string sql = "SELECT * FROM Drivers ORDER BY driverid";
  44. using var conn = new NpgsqlConnection(Conn);
  45. conn.Open();
  46. var adapter = new NpgsqlDataAdapter(sql, conn);
  47. DataTable dt = new DataTable();
  48. adapter.Fill(dt);
  49. dgDrivers.ItemsSource = dt.DefaultView;
  50. }
  51. catch (Exception ex)
  52. {
  53. MessageBox.Show("Ошибка загрузки: " + ex.Message);
  54. }
  55. }
  56. private void BtnRefresh_Click(object sender, RoutedEventArgs e) => LoadDrivers();
  57. private void BtnAdd_Click(object sender, RoutedEventArgs e)
  58. {
  59. if (AppSession.Role == "driver")
  60. {
  61. MessageBox.Show("Нет прав");
  62. return;
  63. }
  64. var dlg = new EditDriverWindow();
  65. dlg.Title = "Добавление водителя";
  66. if (dlg.ShowDialog() == true)
  67. {
  68. try
  69. {
  70. // ✅ ПАРАМЕТРИЗОВАННЫЙ ЗАПРОС (защита от SQL-инъекций)
  71. string sql = "INSERT INTO Drivers (lastname, fullname, tabnumber) " +
  72. "VALUES (@lastname, @fullname, @tabnumber)";
  73. using var conn = new NpgsqlConnection(Conn);
  74. conn.Open();
  75. using var cmd = new NpgsqlCommand(sql, conn);
  76. cmd.Parameters.AddWithValue("@lastname", dlg.LastName ?? "");
  77. cmd.Parameters.AddWithValue("@fullname", dlg.FullName ?? "");
  78. cmd.Parameters.AddWithValue("@tabnumber", dlg.TabNumber ?? "");
  79. int affected = cmd.ExecuteNonQuery();
  80. if (affected > 0)
  81. {
  82. LoadDrivers();
  83. MessageBox.Show("Водитель успешно добавлен", "Успех",
  84. MessageBoxButton.OK, MessageBoxImage.Information);
  85. }
  86. }
  87. catch (PostgresException pgEx)
  88. {
  89. // Специальная обработка ошибок PostgreSQL
  90. string errorMsg = "Ошибка базы данных:\n";
  91. if (pgEx.SqlState == "23505")
  92. errorMsg += "Табельный номер уже существует!";
  93. else if (pgEx.SqlState == "23503")
  94. errorMsg += "Нарушение связей в базе данных.";
  95. else if (pgEx.SqlState == "42P01")
  96. errorMsg += "Таблица не найдена. Проверьте структуру БД.";
  97. else
  98. errorMsg += pgEx.MessageText + "\nКод: " + pgEx.SqlState;
  99. MessageBox.Show(errorMsg, "Ошибка",
  100. MessageBoxButton.OK, MessageBoxImage.Error);
  101. }
  102. catch (Exception ex)
  103. {
  104. MessageBox.Show("Ошибка: " + ex.Message + "\n\n" + ex.StackTrace,
  105. "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
  106. }
  107. }
  108. }
  109. private void BtnEdit_Click(object sender, RoutedEventArgs e)
  110. {
  111. if (AppSession.Role == "driver")
  112. {
  113. MessageBox.Show("Нет прав");
  114. return;
  115. }
  116. if (dgDrivers.SelectedItem == null)
  117. {
  118. MessageBox.Show("Выберите запись");
  119. return;
  120. }
  121. var row = (DataRowView)dgDrivers.SelectedItem;
  122. var dlg = new EditDriverWindow();
  123. dlg.Title = "Изменение водителя";
  124. dlg.DriverId = Convert.ToInt32(row["driverid"]);
  125. dlg.LastName = row["lastname"].ToString();
  126. dlg.FullName = row["fullname"].ToString();
  127. dlg.TabNumber = row["tabnumber"].ToString();
  128. if (dlg.ShowDialog() == true)
  129. {
  130. try
  131. {
  132. // ✅ ПАРАМЕТРИЗОВАННЫЙ ЗАПРОС
  133. string sql = "UPDATE Drivers SET lastname=@lastname, " +
  134. "fullname=@fullname, tabnumber=@tabnumber " +
  135. "WHERE driverid=@driverid";
  136. using var conn = new NpgsqlConnection(Conn);
  137. conn.Open();
  138. using var cmd = new NpgsqlCommand(sql, conn);
  139. cmd.Parameters.AddWithValue("@lastname", dlg.LastName ?? "");
  140. cmd.Parameters.AddWithValue("@fullname", dlg.FullName ?? "");
  141. cmd.Parameters.AddWithValue("@tabnumber", dlg.TabNumber ?? "");
  142. cmd.Parameters.AddWithValue("@driverid", dlg.DriverId);
  143. cmd.ExecuteNonQuery();
  144. LoadDrivers();
  145. MessageBox.Show("Данные обновлены", "Успех",
  146. MessageBoxButton.OK, MessageBoxImage.Information);
  147. }
  148. catch (PostgresException pgEx)
  149. {
  150. string errorMsg = "Ошибка базы данных:\n";
  151. if (pgEx.SqlState == "23505")
  152. errorMsg += "Табельный номер уже существует!";
  153. else
  154. errorMsg += pgEx.MessageText;
  155. MessageBox.Show(errorMsg, "Ошибка",
  156. MessageBoxButton.OK, MessageBoxImage.Error);
  157. }
  158. catch (Exception ex)
  159. {
  160. MessageBox.Show("Ошибка: " + ex.Message);
  161. }
  162. }
  163. }
  164. private void BtnDelete_Click(object sender, RoutedEventArgs e)
  165. {
  166. if (AppSession.Role != "admin")
  167. {
  168. MessageBox.Show("Только администратор может удалять");
  169. return;
  170. }
  171. if (dgDrivers.SelectedItem == null)
  172. {
  173. MessageBox.Show("Выберите запись");
  174. return;
  175. }
  176. var row = (DataRowView)dgDrivers.SelectedItem;
  177. int id = Convert.ToInt32(row["driverid"]);
  178. if (MessageBox.Show("Удалить запись?", "Подтверждение",
  179. MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
  180. {
  181. try
  182. {
  183. string sql = "DELETE FROM Drivers WHERE driverid = @id";
  184. using var conn = new NpgsqlConnection(Conn);
  185. conn.Open();
  186. using var cmd = new NpgsqlCommand(sql, conn);
  187. cmd.Parameters.AddWithValue("@id", id);
  188. cmd.ExecuteNonQuery();
  189. LoadDrivers();
  190. MessageBox.Show("Запись удалена", "Успех",
  191. MessageBoxButton.OK, MessageBoxImage.Information);
  192. }
  193. catch (PostgresException pgEx)
  194. {
  195. string errorMsg = "Ошибка базы данных:\n";
  196. if (pgEx.SqlState == "23503")
  197. errorMsg += "Нельзя удалить: водитель закреплён за машиной!";
  198. else
  199. errorMsg += pgEx.MessageText;
  200. MessageBox.Show(errorMsg, "Ошибка",
  201. MessageBoxButton.OK, MessageBoxImage.Error);
  202. }
  203. catch (Exception ex)
  204. {
  205. MessageBox.Show("Ошибка: " + ex.Message);
  206. }
  207. }
  208. }
  209. }
  210. }