diff --git a/web/src/main/kotlin/ru/ysu/lms/web/AttestationPresentation.kt b/web/src/main/kotlin/ru/ysu/lms/web/AttestationPresentation.kt index d362007..b3c59cf 100644 --- a/web/src/main/kotlin/ru/ysu/lms/web/AttestationPresentation.kt +++ b/web/src/main/kotlin/ru/ysu/lms/web/AttestationPresentation.kt @@ -43,6 +43,13 @@ object AttestationPresentation { fun kindLabel(kind: String): String = KIND_LABELS[kind] ?: kind + /** Понимает и «2», и старые значения вроде «2 семестр»; вне 1–8 — 1. */ + fun semesterNumber(raw: String): Int { + val digits = raw.filter { it.isDigit() } + val value = digits.toIntOrNull() ?: return 1 + return if (value in 1..8) value else 1 + } + fun valueLabel( kind: String, value: String, diff --git a/web/src/main/kotlin/ru/ysu/lms/web/admin/AdminGroupController.kt b/web/src/main/kotlin/ru/ysu/lms/web/admin/AdminGroupController.kt index 619d327..29e3e62 100644 --- a/web/src/main/kotlin/ru/ysu/lms/web/admin/AdminGroupController.kt +++ b/web/src/main/kotlin/ru/ysu/lms/web/admin/AdminGroupController.kt @@ -1,6 +1,7 @@ package ru.ysu.lms.web.admin import jakarta.servlet.http.HttpSession +import org.slf4j.LoggerFactory import org.springframework.http.HttpHeaders import org.springframework.http.MediaType import org.springframework.http.ResponseEntity @@ -59,6 +60,8 @@ class AdminGroupController( markdown: MarkdownRenderer, mapper: ObjectMapper, ) : AdminSupport(api, markdown, mapper) { + private val log = LoggerFactory.getLogger(AdminGroupController::class.java) + @GetMapping fun dashboard( session: HttpSession, @@ -143,7 +146,7 @@ class AdminGroupController( val allLabs = api.listLabs(t) val group = api.groupDetail(t, id) val labs = allLabs.filter { it.status == "published" } - val attestations = GroupAttestationViews.columns(api.listAttestations(t, id)) + val attestations = loadAttestations(t, id) val grades = api.listGrades(t) val gradeBy = grades.associate { "${it.studentId}|${it.labId}" to it.score } val generalCommentBy = grades.associate { "${it.studentId}|${it.labId}" to it.generalComment } @@ -260,6 +263,17 @@ class AdminGroupController( ) } + /** Аттестации не должны ронять всю ведомость, если сервис ещё не обновлён. */ + private fun loadAttestations( + token: String, + groupId: String, + ): List = + GroupAttestationViews.columns( + runCatching { api.listAttestations(token, groupId) } + .onFailure { log.warn("Не удалось загрузить аттестации группы {}", groupId, it) } + .getOrDefault(emptyList()), + ) + private fun averageScore(cells: List): String? { val scores = cells.mapNotNull { it.score?.replace(',', '.')?.toBigDecimalOrNull() } if (scores.isEmpty()) return null diff --git a/web/src/main/kotlin/ru/ysu/lms/web/admin/GroupAttestationViews.kt b/web/src/main/kotlin/ru/ysu/lms/web/admin/GroupAttestationViews.kt index 51b1f07..8e028a3 100644 --- a/web/src/main/kotlin/ru/ysu/lms/web/admin/GroupAttestationViews.kt +++ b/web/src/main/kotlin/ru/ysu/lms/web/admin/GroupAttestationViews.kt @@ -18,7 +18,7 @@ object GroupAttestationViews { id = column.id, kind = column.kind, kindLabel = AttestationPresentation.kindLabel(column.kind), - semester = column.semester, + semester = AttestationPresentation.semesterNumber(column.semester), published = column.published, options = VALUES_BY_KIND[column.kind].orEmpty().map { value -> diff --git a/web/src/main/kotlin/ru/ysu/lms/web/api/ApiDtos.kt b/web/src/main/kotlin/ru/ysu/lms/web/api/ApiDtos.kt index 82824f6..d7b1ceb 100644 --- a/web/src/main/kotlin/ru/ysu/lms/web/api/ApiDtos.kt +++ b/web/src/main/kotlin/ru/ysu/lms/web/api/ApiDtos.kt @@ -275,7 +275,8 @@ data class AttestationDto( val id: String = "", val groupId: String = "", val kind: String = "", - val semester: Int = 1, + /** Строка — чтобы старые ответы с текстовым семестром не ломали разбор. */ + val semester: String = "1", val published: Boolean = false, val results: List = emptyList(), ) diff --git a/web/src/main/kotlin/ru/ysu/lms/web/student/StudentController.kt b/web/src/main/kotlin/ru/ysu/lms/web/student/StudentController.kt index 68d9d66..e0ee807 100644 --- a/web/src/main/kotlin/ru/ysu/lms/web/student/StudentController.kt +++ b/web/src/main/kotlin/ru/ysu/lms/web/student/StudentController.kt @@ -94,7 +94,7 @@ class StudentController( val result = column.results.firstOrNull() StudentAttestationView( kindLabel = AttestationPresentation.kindLabel(column.kind), - semester = column.semester, + semester = AttestationPresentation.semesterNumber(column.semester), valueLabel = result?.let { AttestationPresentation.valueLabel(column.kind, it.value) } ?: "—", positive = result?.let { AttestationPresentation.isPositive(column.kind, it.value) }, )