/
evernotenkai
/
DataBaseXJavaProject
Обзор
Документация
Войти
/
evernotenkai
/
DataBaseXJavaProject
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/app/ui/admin/AdminEnrollmentsView.java
280 строк
13 KB
Makson4ik
Весь проект с src db и прочим делом
12 май 2026, 22:43
12 май 2026, 22:43
431f4aa
Код
Авторство
О чём код?
package app.ui.admin; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import app.model.CourseItem; import app.model.EnrollmentItem; import app.model.StudentItem; import app.service.AdminService; import app.ui.components.PageHeader; import app.ui.components.UiKit; import app.util.Dialogs; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; public class AdminEnrollmentsView extends VBox { private final AdminService service; private final ObservableList<StudentItem> availableMaster = FXCollections.observableArrayList(); private final ObservableList<EnrollmentItem> enrolledMaster = FXCollections.observableArrayList(); private final ObservableList<StudentItem> availableVisible = FXCollections.observableArrayList(); private final ObservableList<EnrollmentItem> enrolledVisible = FXCollections.observableArrayList(); private final ObservableList<CourseItem> courses = FXCollections.observableArrayList(); private final ComboBox<CourseItem> courseBox = new ComboBox<CourseItem>(); private final TextField searchField = new TextField(); private final ComboBox<String> groupFilter = new ComboBox<String>(); private final Label leftCount = UiKit.labeled("", "detail-line"); private final Label rightCount = UiKit.labeled("", "detail-line"); private final TableView<StudentItem> availTable = new TableView<StudentItem>(); private final TableView<EnrollmentItem> enrolledTable = new TableView<EnrollmentItem>(); public AdminEnrollmentsView(final AdminService service) { this.service = service; getStyleClass().add("content-root"); setSpacing(16); getChildren().add(new PageHeader("Назначения", "Зачисление студентов на курсы, быстрый фильтр по группе и массовое назначение без ручного поиска.")); courseBox.setPromptText("Выберите курс"); courseBox.setPrefWidth(340); courseBox.setMaxWidth(Double.MAX_VALUE); searchField.setPromptText("Поиск по студенту / email"); searchField.setPrefWidth(280); groupFilter.setPromptText("Группа"); groupFilter.setPrefWidth(180); groupFilter.setMaxWidth(Double.MAX_VALUE); UiKit.configureTable(availTable); TableColumn<StudentItem, String> a1 = new TableColumn<StudentItem, String>("ФИО"); a1.setCellValueFactory(v -> new SimpleStringProperty(v.getValue().getFullName())); TableColumn<StudentItem, String> a2 = new TableColumn<StudentItem, String>("Группа"); a2.setCellValueFactory(v -> new SimpleStringProperty(v.getValue().getGroupName())); TableColumn<StudentItem, String> a3 = new TableColumn<StudentItem, String>("Логин"); a3.setCellValueFactory(v -> new SimpleStringProperty(v.getValue().getLogin())); availTable.getColumns().addAll(a1, a2, a3); availTable.setItems(availableVisible); UiKit.configureTable(enrolledTable); TableColumn<EnrollmentItem, String> e1 = new TableColumn<EnrollmentItem, String>("Студент"); e1.setCellValueFactory(v -> new SimpleStringProperty(v.getValue().getStudentName())); TableColumn<EnrollmentItem, String> e2 = new TableColumn<EnrollmentItem, String>("Группа"); e2.setCellValueFactory(v -> new SimpleStringProperty(v.getValue().getGroupName())); TableColumn<EnrollmentItem, String> e3 = new TableColumn<EnrollmentItem, String>("Дата"); e3.setCellValueFactory(v -> new SimpleStringProperty(v.getValue().getEnrollmentDate())); enrolledTable.getColumns().addAll(e1, e2, e3); enrolledTable.setItems(enrolledVisible); Button enroll = UiKit.primaryButton("Зачислить >>"); Button enrollMany = UiKit.secondaryButton("Зачислить всех видимых"); Button unenroll = UiKit.dangerButton("<< Отчислить"); Button clearFilters = UiKit.ghostButton("Сбросить фильтры"); enroll.setMaxWidth(Double.MAX_VALUE); enrollMany.setMaxWidth(Double.MAX_VALUE); unenroll.setMaxWidth(Double.MAX_VALUE); clearFilters.setMaxWidth(Double.MAX_VALUE); VBox centerButtons = new VBox(10, enroll, enrollMany, unenroll, clearFilters); centerButtons.setAlignment(Pos.CENTER); enroll.setOnAction(e -> { try { CourseItem course = courseBox.getValue(); StudentItem student = availTable.getSelectionModel().getSelectedItem(); if (course == null || student == null) { Dialogs.info("Назначения", "Выбери курс и студента."); return; } service.enrollStudent(student.getStudentId(), course.getId()); refresh(); } catch (Exception ex) { Dialogs.error("Ошибка зачисления", ex); } }); enrollMany.setOnAction(e -> { try { CourseItem course = courseBox.getValue(); if (course == null) { Dialogs.info("Назначения", "Выбери курс."); return; } if (availableVisible.isEmpty()) { Dialogs.info("Назначения", "Нет студентов, подходящих под фильтр."); return; } if (!Dialogs.confirm("Массовое зачисление", "Зачислить всех видимых студентов на курс \"" + course.getName() + "\"?")) { return; } List<StudentItem> snapshot = new ArrayList<StudentItem>(availableVisible); for (StudentItem student : snapshot) { service.enrollStudent(student.getStudentId(), course.getId()); } refresh(); } catch (Exception ex) { Dialogs.error("Ошибка массового зачисления", ex); } }); unenroll.setOnAction(e -> { try { EnrollmentItem row = enrolledTable.getSelectionModel().getSelectedItem(); if (row == null) { Dialogs.info("Назначения", "Выбери запись о зачислении."); return; } if (Dialogs.confirm("Удаление", "Отчислить студента " + row.getStudentName() + "?")) { service.unenroll(row.getEnrollmentId()); refresh(); } } catch (Exception ex) { Dialogs.error("Ошибка отчисления", ex); } }); clearFilters.setOnAction(e -> { searchField.clear(); groupFilter.getSelectionModel().clearSelection(); if (!groupFilter.getItems().isEmpty()) { groupFilter.getSelectionModel().select(0); } applyFilters(); }); courseBox.valueProperty().addListener((obs, old, sel) -> { reloadCourseData(); applyFilters(); }); searchField.textProperty().addListener((obs, old, sel) -> applyFilters()); groupFilter.valueProperty().addListener((obs, old, sel) -> applyFilters()); courseBox.setOnShowing(e -> refreshCourses()); groupFilter.setOnShowing(e -> refreshGroups()); VBox filterCard = UiKit.card( UiKit.section("Фильтры и быстрые действия"), UiKit.subtitle("Сужай список по группе и поиску, а затем зачисляй несколько студентов одним действием."), UiKit.row(courseBox, searchField), UiKit.row(groupFilter, leftCount), new HBox(10, enrollMany, clearFilters) ); VBox left = UiKit.card(UiKit.section("Доступные студенты"), UiKit.subtitle("Выбирай студентов для зачисления."), availTable); VBox right = UiKit.card(UiKit.section("Уже зачислены"), UiKit.subtitle("Список студентов, которые уже учатся на курсе."), enrolledTable, rightCount); HBox layout = new HBox(16, left, centerButtons, right); HBox.setHgrow(left, Priority.ALWAYS); HBox.setHgrow(right, Priority.ALWAYS); HBox.setHgrow(layout, Priority.ALWAYS); getChildren().addAll(filterCard, layout); refresh(); } public void refresh() { refreshCourses(); refreshGroups(); reloadCourseData(); applyFilters(); } private void refreshCourses() { CourseItem current = courseBox.getValue(); courses.setAll(service.findCourses()); courseBox.getItems().setAll(courses); if (current != null) { for (CourseItem item : courses) { if (item.getId() == current.getId()) { courseBox.getSelectionModel().select(item); break; } } } if (courseBox.getValue() == null && !courses.isEmpty()) { courseBox.getSelectionModel().select(0); } } private void refreshGroups() { Set<String> groups = new LinkedHashSet<String>(); for (StudentItem student : service.findStudents()) { if (student.getGroupName() != null && !student.getGroupName().trim().isEmpty()) { groups.add(student.getGroupName()); } } String currentGroup = groupFilter.getValue(); groupFilter.getItems().setAll("Все группы"); groupFilter.getItems().addAll(groups); if (currentGroup != null && groupFilter.getItems().contains(currentGroup)) { groupFilter.getSelectionModel().select(currentGroup); } else if (!groupFilter.getItems().isEmpty()) { groupFilter.getSelectionModel().select(0); } } private void reloadCourseData() { CourseItem course = courseBox.getValue(); if (course == null) { availableMaster.clear(); enrolledMaster.clear(); return; } availableMaster.setAll(service.findAvailableStudentsForCourse(course.getId())); enrolledMaster.setAll(service.findEnrollmentsByCourse(course.getId())); } private void applyFilters() { String query = searchField.getText() == null ? "" : searchField.getText().trim().toLowerCase(); String group = groupFilter.getValue(); boolean allGroups = group == null || "Все группы".equals(group); availableVisible.clear(); for (StudentItem student : availableMaster) { if ((allGroups || safeEquals(student.getGroupName(), group)) && matchesStudent(student, query)) { availableVisible.add(student); } } enrolledVisible.clear(); for (EnrollmentItem row : enrolledMaster) { if ((allGroups || safeEquals(row.getGroupName(), group)) && matchesEnrollment(row, query)) { enrolledVisible.add(row); } } CourseItem course = courseBox.getValue(); String courseName = course == null ? "-" : course.getName(); leftCount.setText("Доступно: " + availableVisible.size() + " / " + availableMaster.size() + " • Курс: " + courseName); rightCount.setText("Зачислены: " + enrolledVisible.size()); } private boolean matchesStudent(StudentItem student, String query) { if (query.isEmpty()) return true; return contains(student.getFullName(), query) || contains(student.getEmail(), query) || contains(student.getLogin(), query) || contains(student.getGroupName(), query); } private boolean matchesEnrollment(EnrollmentItem row, String query) { if (query.isEmpty()) return true; return contains(row.getStudentName(), query) || contains(row.getGroupName(), query); } private boolean contains(String value, String query) { return value != null && value.toLowerCase().contains(query); } private boolean safeEquals(String a, String b) { return a == null ? b == null : a.equalsIgnoreCase(b); } }