Refactor: split loop/throws helpers; drop deprecated JSON accessors
This commit is contained in:
@@ -124,10 +124,22 @@ class DefenseService(
|
|||||||
studentId: UUID,
|
studentId: UUID,
|
||||||
code: String,
|
code: String,
|
||||||
): DefenseSession {
|
): DefenseSession {
|
||||||
val s = sessions.findByCode(code.trim()) ?: throw BadRequestException("Код не найден")
|
val session = findSessionByCode(code)
|
||||||
if (s.studentId != studentId) throw ForbiddenException("Этот код выдан другому студенту")
|
requireOwnerAndWaiting(session, studentId)
|
||||||
if (s.status != DefenseStatus.waiting.name) throw BadRequestException("Защита по этому коду уже начата")
|
return session
|
||||||
return s
|
}
|
||||||
|
|
||||||
|
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
|
@Transactional
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import ru.ysu.lms.web.api.CreateStudentRequestDto
|
|||||||
import ru.ysu.lms.web.api.DistributeRequestPayload
|
import ru.ysu.lms.web.api.DistributeRequestPayload
|
||||||
import ru.ysu.lms.web.api.GradeSetPayload
|
import ru.ysu.lms.web.api.GradeSetPayload
|
||||||
import ru.ysu.lms.web.api.LabCreatePayload
|
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.LabUpdatePayload
|
||||||
import ru.ysu.lms.web.api.LevelAssignPayload
|
import ru.ysu.lms.web.api.LevelAssignPayload
|
||||||
import ru.ysu.lms.web.api.LevelPayload
|
import ru.ysu.lms.web.api.LevelPayload
|
||||||
@@ -479,29 +480,13 @@ class AdminController(
|
|||||||
var count = 0
|
var count = 0
|
||||||
var skipped = 0
|
var skipped = 0
|
||||||
for ((idx, rawCols) in rows.withIndex()) {
|
for ((idx, rawCols) in rows.withIndex()) {
|
||||||
val cells = rawCols.map { it.trim() }
|
val row = resolveDefenseRow(rawCols, idx, labId, studentByNo, labByNumber)
|
||||||
if (cells.all { it.isBlank() }) continue
|
if (row == null) {
|
||||||
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()) {
|
|
||||||
skipped++
|
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 ""
|
val tail = if (skipped > 0) ", пропущено: $skipped" else ""
|
||||||
redirect.addFlashAttribute("notice", "Импортировано заданий: $count$tail")
|
redirect.addFlashAttribute("notice", "Импортировано заданий: $count$tail")
|
||||||
@@ -511,6 +496,41 @@ class AdminController(
|
|||||||
redirectToGroup(groupId, labId)
|
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 {
|
private fun looksLikeHeader(cells: List<String>): Boolean {
|
||||||
val joined = cells.joinToString(" ").lowercase()
|
val joined = cells.joinToString(" ").lowercase()
|
||||||
return joined.contains("студент") ||
|
return joined.contains("студент") ||
|
||||||
@@ -1250,11 +1270,11 @@ class AdminController(
|
|||||||
val node = mapper.readTree(json)
|
val node = mapper.readTree(json)
|
||||||
buildList {
|
buildList {
|
||||||
node.forEach { el ->
|
node.forEach { el ->
|
||||||
val text = el.path("text").asText("").trim()
|
val text = el.path("text").asString("").trim()
|
||||||
if (text.isNotEmpty()) {
|
if (text.isNotEmpty()) {
|
||||||
add(
|
add(
|
||||||
ru.ysu.lms.web.api
|
ru.ysu.lms.web.api
|
||||||
.CommentPayload(text, el.path("tone").asText("neutral")),
|
.CommentPayload(text, el.path("tone").asString("neutral")),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user