MainWindow.xaml.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. using System;
  2. using System.Data;
  3. using System.Windows;
  4. using Npgsql;
  5. namespace ych
  6. {
  7. public partial class MainWindow : Window
  8. {
  9. private readonly string _connectionString =
  10. "Host=edu-pg.itiscaf.ru;Port=5432;Database=dbwork;" +
  11. "Username=gaukov_dp;Password=4K62ebY72%h;";
  12. private readonly string _userRole;
  13. private string _currentTable = "";
  14. private DataTable _dataTable = new DataTable();
  15. public MainWindow(string userRole)
  16. {
  17. InitializeComponent();
  18. _userRole = userRole;
  19. ApplySecurity();
  20. }
  21. private void ApplySecurity()
  22. {
  23. if (_userRole == "admin")
  24. {
  25. RoleLabel.Text = "Роль: Администратор";
  26. }
  27. else if (_userRole == "teacher")
  28. {
  29. RoleLabel.Text = "Роль: Преподаватель";
  30. BtnDelete.IsEnabled = false;
  31. BtnDelete.Opacity = 0.4;
  32. }
  33. else if (_userRole == "student")
  34. {
  35. RoleLabel.Text = "Роль: Студент";
  36. BtnAdd.Visibility = Visibility.Collapsed;
  37. BtnDelete.Visibility = Visibility.Collapsed;
  38. BtnStudents.Visibility = Visibility.Collapsed;
  39. BtnTeachers.Visibility = Visibility.Collapsed;
  40. BtnGroups.Visibility = Visibility.Collapsed;
  41. }
  42. }
  43. private void LoadTable(string table, string title, string query = "")
  44. {
  45. _currentTable = table;
  46. TitleText.Text = title;
  47. bool isTable = string.IsNullOrEmpty(query);
  48. bool canEdit = _userRole == "admin" || _userRole == "teacher";
  49. ActionPanel.Visibility = (isTable && canEdit)
  50. ? Visibility.Visible : Visibility.Collapsed;
  51. string sql = isTable
  52. ? string.Format("SELECT * FROM {0} ORDER BY 1", table)
  53. : query;
  54. try
  55. {
  56. using (var conn = new NpgsqlConnection(_connectionString))
  57. {
  58. conn.Open();
  59. using (var adapter = new NpgsqlDataAdapter(sql, conn))
  60. {
  61. _dataTable = new DataTable();
  62. adapter.Fill(_dataTable);
  63. MainGrid.IsReadOnly = (_userRole == "student" || !isTable);
  64. MainGrid.ItemsSource = _dataTable.DefaultView;
  65. SetStatus(string.Format("Загружено строк: {0}", _dataTable.Rows.Count));
  66. }
  67. }
  68. }
  69. catch (Exception ex)
  70. {
  71. ShowError(ex.Message);
  72. }
  73. }
  74. private void ShowStudents(object s, RoutedEventArgs e)
  75. {
  76. LoadTable("students", "Студенты");
  77. }
  78. private void ShowSubjects(object s, RoutedEventArgs e)
  79. {
  80. LoadTable("subjects", "Предметы");
  81. }
  82. private void ShowTeachers(object s, RoutedEventArgs e)
  83. {
  84. LoadTable("teachers", "Преподаватели");
  85. }
  86. private void ShowGroups(object s, RoutedEventArgs e)
  87. {
  88. LoadTable("groups", "Группы");
  89. }
  90. private void ShowGrades(object s, RoutedEventArgs e)
  91. {
  92. LoadTable("grades", "Оценки");
  93. }
  94. private void ShowFailing(object s, RoutedEventArgs e)
  95. {
  96. LoadTable("", "Неуспевающие студенты", @"
  97. SELECT s.last_name AS фамилия,
  98. s.first_name AS имя,
  99. gr.id AS группа,
  100. sub.title AS предмет,
  101. g.grade AS оценка
  102. FROM grades g
  103. JOIN students s ON g.record_book_id = s.record_book_id
  104. JOIN groups gr ON s.group_id = gr.id
  105. JOIN subjects sub ON g.subject_id = sub.id
  106. WHERE g.grade = 2
  107. ORDER BY sub.title, s.last_name");
  108. }
  109. private void ShowAvg(object s, RoutedEventArgs e)
  110. {
  111. LoadTable("", "Средний балл по студентам", @"
  112. SELECT s.last_name AS фамилия,
  113. s.first_name AS имя,
  114. ROUND(AVG(g.grade::NUMERIC), 2) AS средний_балл
  115. FROM grades g
  116. JOIN students s ON g.record_book_id = s.record_book_id
  117. GROUP BY s.record_book_id, s.last_name, s.first_name
  118. ORDER BY средний_балл DESC");
  119. }
  120. private void AddRow(object s, RoutedEventArgs e)
  121. {
  122. if (string.IsNullOrEmpty(_currentTable)) return;
  123. _dataTable.Rows.Add(_dataTable.NewRow());
  124. MainGrid.ScrollIntoView(MainGrid.Items[MainGrid.Items.Count - 1]);
  125. SetStatus("Заполните новую строку и нажмите Сохранить");
  126. }
  127. private void SaveRow(object s, RoutedEventArgs e)
  128. {
  129. if (string.IsNullOrEmpty(_currentTable)) return;
  130. // 1. Проверяем, есть ли пустые строки
  131. foreach (DataRow row in _dataTable.Rows)
  132. {
  133. // RowState.Added означает, что строка новая и еще не сохранена
  134. if (row.RowState == DataRowState.Added)
  135. {
  136. bool isEmpty = true;
  137. // Проходим по всем колонкам строки
  138. foreach (DataColumn col in _dataTable.Columns)
  139. {
  140. // Если хоть одно поле не пустое и не DBNull - строка заполнена
  141. if (row[col] != DBNull.Value && !string.IsNullOrEmpty(row[col].ToString()))
  142. {
  143. isEmpty = false;
  144. break;
  145. }
  146. }
  147. // Если строка пустая - удаляем её, чтобы не вызывать ошибку БД
  148. if (isEmpty)
  149. {
  150. row.Delete();
  151. }
  152. }
  153. }
  154. // Если после чистки ничего не осталось для сохранения - выходим
  155. if (_dataTable.GetChanges() == null)
  156. {
  157. SetStatus("Пустые строки удалены. Заполните данные.");
  158. return;
  159. }
  160. try
  161. {
  162. using (var conn = new NpgsqlConnection(_connectionString))
  163. {
  164. conn.Open();
  165. using (var adapter = new NpgsqlDataAdapter(
  166. $"SELECT * FROM gaukov_dp.{_currentTable} WHERE 1=0", conn))
  167. {
  168. using (var builder = new NpgsqlCommandBuilder(adapter))
  169. {
  170. adapter.Update(_dataTable);
  171. _dataTable.AcceptChanges();
  172. SetStatus("Данные успешно сохранены");
  173. LoadTable(_currentTable, TitleText.Text);
  174. }
  175. }
  176. }
  177. }
  178. catch (Exception ex)
  179. {
  180. ShowError(ex.Message);
  181. }
  182. }
  183. private void DeleteRow(object s, RoutedEventArgs e)
  184. {
  185. if (_userRole != "admin")
  186. {
  187. ShowError("Недостаточно прав для удаления");
  188. return;
  189. }
  190. if (!(MainGrid.SelectedItem is DataRowView row)) return;
  191. var result = MessageBox.Show(
  192. "Удалить выбранную запись? (Все связанные оценки тоже будут удалены)",
  193. "Подтверждение",
  194. MessageBoxButton.YesNo, MessageBoxImage.Warning);
  195. if (result != MessageBoxResult.Yes) return;
  196. try
  197. {
  198. // Получаем ID студента (предполагаем, что это первая колонка или record_book_id)
  199. // Тебе нужно знать точное имя колонки ID в таблице students
  200. var studentId = row["record_book_id"]; // Или row["id"], посмотри в таблице
  201. using (var conn = new NpgsqlConnection(_connectionString))
  202. {
  203. conn.Open();
  204. using (var transaction = conn.BeginTransaction())
  205. {
  206. try
  207. {
  208. // 1. Сначала удаляем оценки студента
  209. string deleteGradesSql = "DELETE FROM gaukov_dp.grades WHERE record_book_id = @id";
  210. using (var cmd = new NpgsqlCommand(deleteGradesSql, conn, transaction))
  211. {
  212. cmd.Parameters.AddWithValue("id", studentId);
  213. cmd.ExecuteNonQuery();
  214. }
  215. // 2. Теперь удаляем самого студента через DataTable
  216. row.Row.Delete();
  217. using (var adapter = new NpgsqlDataAdapter(
  218. $"SELECT * FROM gaukov_dp.{_currentTable} WHERE 1=0", conn))
  219. {
  220. adapter.SelectCommand.Transaction = transaction;
  221. using (var builder = new NpgsqlCommandBuilder(adapter))
  222. {
  223. adapter.Update(_dataTable);
  224. }
  225. }
  226. transaction.Commit();
  227. _dataTable.AcceptChanges();
  228. SetStatus("Запись и связанные данные удалены");
  229. }
  230. catch
  231. {
  232. transaction.Rollback();
  233. throw;
  234. }
  235. }
  236. }
  237. }
  238. catch (Exception ex)
  239. {
  240. row.Row.RejectChanges();
  241. ShowError(ex.Message);
  242. }
  243. }
  244. private void Logout_Click(object s, RoutedEventArgs e)
  245. {
  246. var login = new LoginWindow();
  247. login.Show();
  248. Close();
  249. }
  250. private void SetStatus(string msg)
  251. {
  252. StatusText.Text = msg;
  253. }
  254. private void ShowError(string msg)
  255. {
  256. StatusText.Text = string.Format("Ошибка: {0}", msg);
  257. MessageBox.Show(msg, "Ошибка",
  258. MessageBoxButton.OK, MessageBoxImage.Error);
  259. }
  260. }
  261. }