/
evernotenkai
/
DataBaseXJavaProject
Обзор
Документация
Войти
/
evernotenkai
/
DataBaseXJavaProject
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/app/ui/teacher/TeacherSubmissionWindow.java
252 строки
10 KB
Makson4ik
Весь проект с src db и прочим делом
12 май 2026, 22:43
12 май 2026, 22:43
431f4aa
Код
Авторство
О чём код?
package app.ui.teacher; import java.awt.Desktop; import java.io.File; import java.io.FileOutputStream; import java.nio.file.Files; import app.model.SubmissionAttachmentData; import app.model.SubmissionItem; import app.service.LmsService; import app.ui.components.NumericField; import app.ui.components.UiKit; import app.util.Dialogs; import app.util.HtmlUtil; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.scene.web.WebView; import javafx.stage.FileChooser; import javafx.stage.Modality; import javafx.stage.Stage; public class TeacherSubmissionWindow extends Stage { private final LmsService service; private final int submissionId; private final Runnable onSaved; private SubmissionItem item; private final Label courseValue = UiKit.labeled("-", "detail-value"); private final Label assignmentValue = UiKit.labeled("-", "detail-value"); private final Label studentValue = UiKit.labeled("-", "detail-value"); private final Label dateValue = UiKit.labeled("-", "detail-value"); private final Label statusChipHost = UiKit.labeled("", "detail-value"); private final Label attachmentValue = UiKit.labeled("Вложение отсутствует", "detail-value"); private final WebView workView = new WebView(); private final NumericField gradeField = new NumericField(1, 100); private final javafx.scene.control.TextArea commentArea = new javafx.scene.control.TextArea(); public TeacherSubmissionWindow(LmsService service, SubmissionItem item, Runnable onSaved) { this.service = service; this.submissionId = item.getId(); this.onSaved = onSaved; this.item = item; initModality(Modality.NONE); setTitle("Проверка работы студента"); setMinWidth(1080); setMinHeight(780); gradeField.setPromptText("1..100"); workView.setPrefHeight(320); VBox.setVgrow(workView, Priority.ALWAYS); commentArea.setWrapText(true); commentArea.setPrefRowCount(6); VBox.setVgrow(commentArea, Priority.ALWAYS); VBox details = UiKit.card( UiKit.section("Сведения о работе"), UiKit.subtitle("Работа открывается в отдельном окне для удобной проверки."), infoGrid(), UiKit.card( UiKit.section("Текст / HTML работы"), UiKit.subtitle("Если студент использовал форматирование, документ отображается как страница."), workView ), attachmentCard() ); VBox grading = UiKit.card( UiKit.section("Проверка и оценка"), UiKit.subtitle("Измени оценку или комментарий и сохрани результат."), UiKit.fieldBox("Оценка", gradeField, "Ввод только цифрами: 1..100"), UiKit.fieldBox("Комментарий преподавателя", commentArea, "Коротко опиши результат и замечания") ); Button save = UiKit.primaryButton("Сохранить"); Button refresh = UiKit.secondaryButton("Обновить"); Button closeBtn = UiKit.ghostButton("Закрыть"); save.setOnAction(e -> { try { Integer gradeValue = gradeField.getIntValue(); if (gradeValue == null) { Dialogs.info("Проверка", "Укажи оценку от 1 до 100."); return; } service.upsertGrade(submissionId, gradeValue.intValue(), commentArea.getText()); reload(); if (onSaved != null) { onSaved.run(); } Dialogs.info("Проверка", "Оценка сохранена."); } catch (Exception ex) { Dialogs.error("Ошибка проверки", ex); } }); refresh.setOnAction(e -> reload()); closeBtn.setOnAction(e -> close()); HBox buttons = new HBox(10, save, refresh, closeBtn); buttons.setAlignment(Pos.CENTER_LEFT); grading.getChildren().add(buttons); HBox.setHgrow(details, Priority.ALWAYS); HBox.setHgrow(grading, Priority.NEVER); HBox root = new HBox(16, details, grading); root.setPadding(new Insets(18)); root.setAlignment(Pos.TOP_LEFT); Scene scene = new Scene(root, 1080, 780); scene.getStylesheets().add(getClass().getClassLoader().getResource("app.css").toExternalForm()); setScene(scene); reload(); } private VBox attachmentCard() { Button openAttachmentBtn = UiKit.ghostButton("Открыть вложение"); Button saveAttachmentBtn = UiKit.ghostButton("Сохранить как"); openAttachmentBtn.setOnAction(e -> openAttachment()); saveAttachmentBtn.setOnAction(e -> saveAttachmentAs()); HBox row = new HBox(10, attachmentValue, openAttachmentBtn, saveAttachmentBtn); row.setAlignment(Pos.CENTER_LEFT); return UiKit.card( UiKit.section("Вложение"), UiKit.subtitle("Файл студента можно открыть или сохранить на диск."), row ); } private javafx.scene.layout.GridPane infoGrid() { javafx.scene.layout.GridPane grid = new javafx.scene.layout.GridPane(); grid.setHgap(14); grid.setVgap(10); grid.add(UiKit.labeled("Курс", "detail-line"), 0, 0); grid.add(courseValue, 1, 0); grid.add(UiKit.labeled("Задание", "detail-line"), 0, 1); grid.add(assignmentValue, 1, 1); grid.add(UiKit.labeled("Студент", "detail-line"), 0, 2); grid.add(studentValue, 1, 2); grid.add(UiKit.labeled("Дата сдачи", "detail-line"), 0, 3); grid.add(dateValue, 1, 3); grid.add(UiKit.labeled("Статус", "detail-line"), 0, 4); grid.add(statusChipHost, 1, 4); return grid; } private void reload() { SubmissionItem fresh = service.findSubmissionById(submissionId); if (fresh == null) { Dialogs.info("Проверка", "Работа не найдена."); close(); return; } this.item = fresh; courseValue.setText(fresh.getCourseName()); assignmentValue.setText(fresh.getAssignmentTitle()); studentValue.setText(fresh.getStudentName()); dateValue.setText(fresh.getSubmissionDate()); statusChipHost.setGraphic(UiKit.chip(fresh.getStatus(), UiKit.statusClass(fresh.getStatus()))); workView.getEngine().loadContent(HtmlUtil.wrapHtml(fresh.getContentNote())); gradeField.setIntValue(fresh.getGradeValue()); commentArea.setText(fresh.getTeacherComment() == null ? "" : fresh.getTeacherComment()); attachmentValue.setText(fresh.getAttachmentName() == null ? "Вложение отсутствует" : fresh.getAttachmentName()); } private void openAttachment() { try { SubmissionAttachmentData attachment = service.findSubmissionAttachment(submissionId); if (attachment == null || !attachment.hasData()) { Dialogs.info("Вложение", "У этой работы нет файла."); return; } File tmp = saveAttachmentToTemp(attachment); if (Desktop.isDesktopSupported()) { Desktop.getDesktop().open(tmp); } else { Dialogs.info("Вложение", "Файл сохранён: " + tmp.getAbsolutePath()); } } catch (Exception ex) { Dialogs.error("Вложение", ex); } } private void saveAttachmentAs() { try { SubmissionAttachmentData attachment = service.findSubmissionAttachment(submissionId); if (attachment == null || !attachment.hasData()) { Dialogs.info("Вложение", "У этой работы нет файла."); return; } FileChooser chooser = new FileChooser(); String name = attachment.getFileName() == null ? "attachment.bin" : attachment.getFileName(); chooser.setInitialFileName(name); File file = chooser.showSaveDialog(this); if (file == null) { return; } Files.write(file.toPath(), attachment.getData()); Dialogs.info("Вложение", "Файл сохранён."); } catch (Exception ex) { Dialogs.error("Вложение", ex); } } public static void saveAndOpenAttachment(SubmissionAttachmentData attachment, String prefix) throws Exception { if (attachment == null || !attachment.hasData()) { return; } String name = attachment.getFileName() == null ? prefix + "-attachment.bin" : attachment.getFileName(); String suffix = ""; int dot = name.lastIndexOf('.'); if (dot >= 0 && dot < name.length() - 1) { suffix = name.substring(dot); } File temp = File.createTempFile(prefix + "-", suffix.isEmpty() ? ".tmp" : suffix); temp.deleteOnExit(); try (FileOutputStream out = new FileOutputStream(temp)) { out.write(attachment.getData()); } if (Desktop.isDesktopSupported()) { Desktop.getDesktop().open(temp); } } private File saveAttachmentToTemp(SubmissionAttachmentData attachment) throws Exception { String name = attachment.getFileName() == null ? "submission-attachment.bin" : attachment.getFileName(); String suffix = ""; int dot = name.lastIndexOf('.'); if (dot >= 0 && dot < name.length() - 1) { suffix = name.substring(dot); } File temp = File.createTempFile("mini-lms-", suffix.isEmpty() ? ".tmp" : suffix); temp.deleteOnExit(); try (FileOutputStream out = new FileOutputStream(temp)) { out.write(attachment.getData()); } return temp; } }