Refactor: split loop/throws helpers; drop deprecated JSON accessors

This commit is contained in:
2026-09-27 22:02:56 +03:00
parent 577a2c8f41
commit 82b912ba46
2 changed files with 59 additions and 27 deletions

View File

@@ -124,10 +124,22 @@ class DefenseService(
studentId: UUID,
code: String,
): DefenseSession {
val s = sessions.findByCode(code.trim()) ?: throw BadRequestException("Код не найден")
if (s.studentId != studentId) throw ForbiddenException("Этот код выдан другому студенту")
if (s.status != DefenseStatus.waiting.name) throw BadRequestException("Защита по этому коду уже начата")
return s
val session = findSessionByCode(code)
requireOwnerAndWaiting(session, studentId)
return session
}
private fun findSessionByCode(code: String): DefenseSession =
sessions.findByCode(code.trim()) ?: throw BadRequestException("Код не найден")
private fun requireOwnerAndWaiting(
session: DefenseSession,
studentId: UUID,
) {
if (session.studentId != studentId) throw ForbiddenException("Этот код выдан другому студенту")
if (session.status != DefenseStatus.waiting.name) {
throw BadRequestException("Защита по этому коду уже начата")
}
}
@Transactional

View File

@@ -20,6 +20,7 @@ import ru.ysu.lms.web.api.CreateStudentRequestDto
import ru.ysu.lms.web.api.DistributeRequestPayload
import ru.ysu.lms.web.api.GradeSetPayload
import ru.ysu.lms.web.api.LabCreatePayload
import ru.ysu.lms.web.api.LabSummaryDto
import ru.ysu.lms.web.api.LabUpdatePayload
import ru.ysu.lms.web.api.LevelAssignPayload
import ru.ysu.lms.web.api.LevelPayload
@@ -479,29 +480,13 @@ class AdminController(
var count = 0
var skipped = 0
for ((idx, rawCols) in rows.withIndex()) {
val cells = rawCols.map { it.trim() }
if (cells.all { it.isBlank() }) continue
if (idx == 0 && looksLikeHeader(cells)) continue
var sid: String? = null
var lid: String? = labId?.takeIf { it.isNotBlank() }
var md: String? = null
when {
cells.size >= 3 -> {
sid = studentByNo[cells[0]]
lid = labByNumber[cells[1]]?.id ?: lid
md = cells.drop(2).joinToString("; ")
}
cells.size == 2 -> {
sid = studentByNo[cells[0]]
md = cells[1]
}
}
if (sid == null || lid.isNullOrBlank() || md.isNullOrBlank()) {
val row = resolveDefenseRow(rawCols, idx, labId, studentByNo, labByNumber)
if (row == null) {
skipped++
continue
} else {
api.assignDefense(t, row.studentId, row.labId, row.assignmentMd.replace("\\n", "\n"))
count++
}
api.assignDefense(t, sid, lid, md.replace("\\n", "\n"))
count++
}
val tail = if (skipped > 0) ", пропущено: $skipped" else ""
redirect.addFlashAttribute("notice", "Импортировано заданий: $count$tail")
@@ -511,6 +496,41 @@ class AdminController(
redirectToGroup(groupId, labId)
}
private data class DefenseRow(
val studentId: String,
val labId: String,
val assignmentMd: String,
)
/** Разбирает строку CSV с заданием на защиту; null — строку нужно пропустить. */
private fun resolveDefenseRow(
rawCols: List<String>,
index: Int,
defaultLabId: String?,
studentByNo: Map<String, String>,
labByNumber: Map<String, LabSummaryDto>,
): DefenseRow? {
val cells = rawCols.map { it.trim() }
if (cells.all { it.isBlank() }) return null
if (index == 0 && looksLikeHeader(cells)) return null
var sid: String? = null
var lid: String? = defaultLabId?.takeIf { it.isNotBlank() }
var md: String? = null
when {
cells.size >= 3 -> {
sid = studentByNo[cells[0]]
lid = labByNumber[cells[1]]?.id ?: lid
md = cells.drop(2).joinToString("; ")
}
cells.size == 2 -> {
sid = studentByNo[cells[0]]
md = cells[1]
}
}
if (sid == null || lid.isNullOrBlank() || md.isNullOrBlank()) return null
return DefenseRow(sid, lid, md)
}
private fun looksLikeHeader(cells: List<String>): Boolean {
val joined = cells.joinToString(" ").lowercase()
return joined.contains("студент") ||
@@ -1250,11 +1270,11 @@ class AdminController(
val node = mapper.readTree(json)
buildList {
node.forEach { el ->
val text = el.path("text").asText("").trim()
val text = el.path("text").asString("").trim()
if (text.isNotEmpty()) {
add(
ru.ysu.lms.web.api
.CommentPayload(text, el.path("tone").asText("neutral")),
.CommentPayload(text, el.path("tone").asString("neutral")),
)
}
}