Refactor: bind admin forms via @ModelAttribute DTOs; detekt fully default
This commit is contained in:
@@ -2,6 +2,7 @@ package ru.ysu.lms.web.admin
|
||||
|
||||
import jakarta.servlet.http.HttpSession
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
@@ -26,38 +27,34 @@ class AdminDefenseController(
|
||||
@PostMapping("/labs/{labId}/defense/assign")
|
||||
fun assignDefense(
|
||||
@PathVariable labId: String,
|
||||
@RequestParam studentId: String,
|
||||
@RequestParam assignmentMd: String,
|
||||
@RequestParam(required = false) groupId: String?,
|
||||
@ModelAttribute form: DefenseForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
try {
|
||||
api.assignDefense(token(session), studentId, labId, assignmentMd)
|
||||
api.assignDefense(token(session), form.studentId, labId, form.assignmentMd)
|
||||
redirect.addFlashAttribute("notice", "Индивидуальное задание сохранено")
|
||||
redirectToGroup(groupId, labId)
|
||||
redirectToGroup(form.groupId, labId)
|
||||
} catch (ex: ApiException) {
|
||||
redirect.addFlashAttribute("error", ex.message)
|
||||
redirectToGroup(groupId, labId)
|
||||
redirectToGroup(form.groupId, labId)
|
||||
}
|
||||
|
||||
/** Назначение/правка индивидуального задания со страницы группы. */
|
||||
@PostMapping("/defenses/save")
|
||||
fun saveDefense(
|
||||
@RequestParam studentId: String,
|
||||
@ModelAttribute form: DefenseForm,
|
||||
@RequestParam labId: String,
|
||||
@RequestParam assignmentMd: String,
|
||||
@RequestParam(required = false) groupId: String?,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
try {
|
||||
api.assignDefense(token(session), studentId, labId, assignmentMd)
|
||||
api.assignDefense(token(session), form.studentId, labId, form.assignmentMd)
|
||||
redirect.addFlashAttribute("notice", "Индивидуальное задание сохранено")
|
||||
redirectToGroup(groupId, labId)
|
||||
redirectToGroup(form.groupId, labId)
|
||||
} catch (ex: ApiException) {
|
||||
redirect.addFlashAttribute("error", ex.message)
|
||||
redirectToGroup(groupId, labId)
|
||||
redirectToGroup(form.groupId, labId)
|
||||
}
|
||||
|
||||
@PostMapping("/labs/{labId}/defense/import")
|
||||
|
||||
@@ -2,6 +2,7 @@ package ru.ysu.lms.web.admin
|
||||
|
||||
import jakarta.servlet.http.HttpSession
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
@@ -29,14 +30,12 @@ class AdminDistributeController(
|
||||
@PostMapping("/groups/{gid}/set-level")
|
||||
fun setStudentLevel(
|
||||
@PathVariable gid: String,
|
||||
@RequestParam studentId: String,
|
||||
@RequestParam labId: String,
|
||||
@RequestParam labLevelId: String,
|
||||
@ModelAttribute form: StudentLevelForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
try {
|
||||
api.setLevel(token(session), LevelAssignPayload(studentId, labId, labLevelId))
|
||||
api.setLevel(token(session), LevelAssignPayload(form.studentId, form.labId, form.labLevelId))
|
||||
redirect.addFlashAttribute("notice", "Уровень обновлён — вариант подобран автоматически")
|
||||
"redirect:/admin/groups/$gid"
|
||||
} catch (ex: ApiException) {
|
||||
@@ -47,14 +46,12 @@ class AdminDistributeController(
|
||||
@PostMapping("/groups/{gid}/pin-variant")
|
||||
fun pinStudentVariant(
|
||||
@PathVariable gid: String,
|
||||
@RequestParam studentId: String,
|
||||
@RequestParam labId: String,
|
||||
@RequestParam variantId: String,
|
||||
@ModelAttribute form: PinVariantForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
try {
|
||||
val result = api.assignVariant(token(session), AssignVariantPayload(studentId, labId, variantId))
|
||||
val result = api.assignVariant(token(session), AssignVariantPayload(form.studentId, form.labId, form.variantId))
|
||||
redirect.addFlashAttribute("notice", "Закреплён вариант ${result.variantNumber}")
|
||||
"redirect:/admin/groups/$gid"
|
||||
} catch (ex: ApiException) {
|
||||
|
||||
92
web/src/main/kotlin/ru/ysu/lms/web/admin/AdminForms.kt
Normal file
92
web/src/main/kotlin/ru/ysu/lms/web/admin/AdminForms.kt
Normal file
@@ -0,0 +1,92 @@
|
||||
package ru.ysu.lms.web.admin
|
||||
|
||||
// Формы админ-контроллеров: связываются через @ModelAttribute.
|
||||
// Имена полей совпадают с именами полей в шаблонах (то же, что было в @RequestParam).
|
||||
|
||||
data class CreateStudentForm(
|
||||
val studentNo: String = "",
|
||||
val lastName: String = "",
|
||||
val firstName: String? = null,
|
||||
val middleName: String? = null,
|
||||
val basis: String? = null,
|
||||
)
|
||||
|
||||
data class StudentLevelForm(
|
||||
val studentId: String = "",
|
||||
val labId: String = "",
|
||||
val labLevelId: String = "",
|
||||
)
|
||||
|
||||
data class PinVariantForm(
|
||||
val studentId: String = "",
|
||||
val labId: String = "",
|
||||
val variantId: String = "",
|
||||
)
|
||||
|
||||
data class DefenseForm(
|
||||
val studentId: String = "",
|
||||
val assignmentMd: String = "",
|
||||
val groupId: String? = null,
|
||||
)
|
||||
|
||||
data class CreateLabForm(
|
||||
val number: Int = 0,
|
||||
val title: String = "",
|
||||
val deadlineAt: String? = null,
|
||||
val defenseAt: String? = null,
|
||||
val pointsMax: String = "",
|
||||
val status: String = "",
|
||||
val descriptionMd: String = "",
|
||||
val levels: String = "",
|
||||
)
|
||||
|
||||
data class SaveLevelForm(
|
||||
val levelId: String? = null,
|
||||
val code: String = "",
|
||||
val title: String = "",
|
||||
)
|
||||
|
||||
data class SaveVariantForm(
|
||||
val variantId: String? = null,
|
||||
val labLevelId: String = "",
|
||||
val number: String = "",
|
||||
val title: String = "",
|
||||
val statementMd: String = "",
|
||||
)
|
||||
|
||||
data class EditLabForm(
|
||||
val title: String = "",
|
||||
val deadlineAt: String? = null,
|
||||
val defenseAt: String? = null,
|
||||
val pointsMax: String = "",
|
||||
val status: String = "",
|
||||
val descriptionMd: String = "",
|
||||
val action: String = "save",
|
||||
val levelIds: List<String>? = null,
|
||||
val levelTitles: List<String>? = null,
|
||||
val variantIds: List<String>? = null,
|
||||
val variantLevelIds: List<String>? = null,
|
||||
val variantNumbers: List<String>? = null,
|
||||
val variantTitles: List<String>? = null,
|
||||
val variantStatements: List<String>? = null,
|
||||
val newLevelCode: String? = null,
|
||||
val newLevelTitle: String? = null,
|
||||
val addLevelId: String? = null,
|
||||
val addNumber: String? = null,
|
||||
val addTitle: String? = null,
|
||||
val addStatementMd: String? = null,
|
||||
)
|
||||
|
||||
data class SetGradeForm(
|
||||
val studentId: String = "",
|
||||
val labId: String = "",
|
||||
val score: String = "",
|
||||
val commentsJson: String? = null,
|
||||
)
|
||||
|
||||
data class SubmissionDownloadForm(
|
||||
val group: String? = null,
|
||||
val no: String? = null,
|
||||
val name: String? = null,
|
||||
val attempt: String? = null,
|
||||
)
|
||||
@@ -7,6 +7,7 @@ import org.springframework.http.ResponseEntity
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.ui.Model
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
@@ -188,7 +189,7 @@ class AdminGroupController(
|
||||
buildDefenseRows(t, group, labs)
|
||||
|
||||
val candidates = runCatching { api.groupCandidates(t, id) }.getOrDefault(emptyList())
|
||||
fillGroupModel(model, group, labs, candidates, rows, defenseRows, publishedLabs)
|
||||
fillGroupModel(model, GroupViewModel(group, labs, candidates, rows, defenseRows, publishedLabs))
|
||||
return "admin/group"
|
||||
}
|
||||
|
||||
@@ -223,36 +224,37 @@ class AdminGroupController(
|
||||
}
|
||||
}.sortedWith(compareBy({ it.fullName.lowercase() }, { it.labNumber }))
|
||||
|
||||
private data class GroupViewModel(
|
||||
val group: GroupDetailDto,
|
||||
val labs: List<LabSummaryDto>,
|
||||
val candidates: List<StudentCandidateDto>,
|
||||
val rows: List<GroupStudentRow>,
|
||||
val defenseRows: List<GroupDefenseRow>,
|
||||
val publishedLabs: Set<String>,
|
||||
)
|
||||
|
||||
private fun fillGroupModel(
|
||||
model: Model,
|
||||
group: GroupDetailDto,
|
||||
labs: List<LabSummaryDto>,
|
||||
candidates: List<StudentCandidateDto>,
|
||||
rows: List<GroupStudentRow>,
|
||||
defenseRows: List<GroupDefenseRow>,
|
||||
publishedLabs: Set<String>,
|
||||
view: GroupViewModel,
|
||||
) {
|
||||
model.addAttribute("group", group)
|
||||
model.addAttribute("labs", labs)
|
||||
model.addAttribute("candidates", candidates)
|
||||
model.addAttribute("studentGrades", rows)
|
||||
model.addAttribute("defenseRows", defenseRows)
|
||||
model.addAttribute("publishedLabIds", publishedLabs)
|
||||
model.addAttribute("group", view.group)
|
||||
model.addAttribute("labs", view.labs)
|
||||
model.addAttribute("candidates", view.candidates)
|
||||
model.addAttribute("studentGrades", view.rows)
|
||||
model.addAttribute("defenseRows", view.defenseRows)
|
||||
model.addAttribute("publishedLabIds", view.publishedLabs)
|
||||
}
|
||||
|
||||
@PostMapping("/groups/{id}/grades")
|
||||
fun setGrade(
|
||||
@PathVariable id: String,
|
||||
@RequestParam studentId: String,
|
||||
@RequestParam labId: String,
|
||||
@RequestParam score: String,
|
||||
@RequestParam(required = false) commentsJson: String?,
|
||||
@ModelAttribute form: SetGradeForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
try {
|
||||
val comments = parseComments(commentsJson ?: "[]")
|
||||
api.setGrade(token(session), GradeSetPayload(studentId, labId, score, comments))
|
||||
val comments = parseComments(form.commentsJson ?: "[]")
|
||||
api.setGrade(token(session), GradeSetPayload(form.studentId, form.labId, form.score, comments))
|
||||
redirect.addFlashAttribute("notice", "Оценка сохранена")
|
||||
"redirect:/admin/groups/$id"
|
||||
} catch (ex: ApiException) {
|
||||
@@ -294,14 +296,11 @@ class AdminGroupController(
|
||||
@GetMapping("/submissions/{id}/download")
|
||||
fun downloadSubmissionAsAdmin(
|
||||
@PathVariable id: String,
|
||||
@RequestParam(required = false) group: String?,
|
||||
@RequestParam(required = false) no: String?,
|
||||
@RequestParam(required = false) name: String?,
|
||||
@RequestParam(required = false) attempt: String?,
|
||||
@ModelAttribute form: SubmissionDownloadForm,
|
||||
session: HttpSession,
|
||||
): ResponseEntity<ByteArray> {
|
||||
val file = api.downloadSubmissionAsAdmin(token(session), id)
|
||||
val filename = submissionFilename(group, no, name, attempt) ?: file.filename
|
||||
val filename = submissionFilename(form.group, form.no, form.name, form.attempt) ?: file.filename
|
||||
val encoded = java.net.URLEncoder.encode(filename, java.nio.charset.StandardCharsets.UTF_8)
|
||||
return ResponseEntity
|
||||
.ok()
|
||||
|
||||
@@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpSession
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.ui.Model
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
@@ -141,7 +142,10 @@ class AdminLabController(
|
||||
val defaultLevel = lab.levels.firstOrNull()
|
||||
|
||||
val assignmentGroups =
|
||||
buildAssignmentGroups(t, lab, levelByStudent, assignmentByStudent, submissionsByStudent, defaultLevel)
|
||||
buildAssignmentGroups(
|
||||
t,
|
||||
LabAssignmentData(lab, levelByStudent, assignmentByStudent, submissionsByStudent, defaultLevel),
|
||||
)
|
||||
|
||||
model.addAttribute("lab", lab)
|
||||
model.addAttribute("descriptionHtml", markdown.render(lab.descriptionMd))
|
||||
@@ -176,14 +180,18 @@ class AdminLabController(
|
||||
return "admin/lab"
|
||||
}
|
||||
|
||||
private data class LabAssignmentData(
|
||||
val lab: LabDetailDto,
|
||||
val levelByStudent: Map<String, LevelAssignmentResultDto>,
|
||||
val assignmentByStudent: Map<String, VariantAssignmentResultDto>,
|
||||
val submissionsByStudent: Map<String, SubmissionDto>,
|
||||
val defaultLevel: LabLevelDetailDto?,
|
||||
)
|
||||
|
||||
/** Строки «группа → студенты» со их уровнем, вариантом и последней сдачей. */
|
||||
private fun buildAssignmentGroups(
|
||||
token: String,
|
||||
lab: LabDetailDto,
|
||||
levelByStudent: Map<String, LevelAssignmentResultDto>,
|
||||
assignmentByStudent: Map<String, VariantAssignmentResultDto>,
|
||||
submissionsByStudent: Map<String, SubmissionDto>,
|
||||
defaultLevel: LabLevelDetailDto?,
|
||||
data: LabAssignmentData,
|
||||
): List<AdminLabGroup> =
|
||||
api.listGroups(token).map { g ->
|
||||
val detail = api.groupDetail(token, g.id)
|
||||
@@ -191,9 +199,9 @@ class AdminLabController(
|
||||
groupName = g.name,
|
||||
students =
|
||||
detail.students.map { s ->
|
||||
val levelState = levelByStudent[s.id]
|
||||
val level = lab.levels.firstOrNull { it.id == levelState?.labLevelId } ?: defaultLevel
|
||||
val va = assignmentByStudent[s.id]
|
||||
val levelState = data.levelByStudent[s.id]
|
||||
val level = data.lab.levels.firstOrNull { it.id == levelState?.labLevelId } ?: data.defaultLevel
|
||||
val va = data.assignmentByStudent[s.id]
|
||||
AdminLabStudent(
|
||||
studentId = s.id,
|
||||
fullName = s.fullName,
|
||||
@@ -204,9 +212,9 @@ class AdminLabController(
|
||||
variantId = va?.variantId,
|
||||
variantNumber = va?.variantNumber,
|
||||
source = if (va?.manual == true) "вручную" else "авто",
|
||||
submissionId = submissionsByStudent[s.id]?.id,
|
||||
submissionSeq = submissionsByStudent[s.id]?.seq,
|
||||
submissionFiles = submissionsByStudent[s.id]?.files ?: emptyList(),
|
||||
submissionId = data.submissionsByStudent[s.id]?.id,
|
||||
submissionSeq = data.submissionsByStudent[s.id]?.seq,
|
||||
submissionFiles = data.submissionsByStudent[s.id]?.files ?: emptyList(),
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -231,21 +239,14 @@ class AdminLabController(
|
||||
|
||||
@PostMapping("/labs/create")
|
||||
fun createLab(
|
||||
@RequestParam number: Int,
|
||||
@RequestParam title: String,
|
||||
@RequestParam(required = false) deadlineAt: String?,
|
||||
@RequestParam(required = false) defenseAt: String?,
|
||||
@RequestParam pointsMax: String,
|
||||
@RequestParam status: String,
|
||||
@RequestParam descriptionMd: String,
|
||||
@RequestParam levels: String,
|
||||
@ModelAttribute form: CreateLabForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
try {
|
||||
// levels: строки "код;название" по одной на строку
|
||||
val levelList =
|
||||
levels
|
||||
form.levels
|
||||
.lines()
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotBlank() }
|
||||
@@ -261,17 +262,17 @@ class AdminLabController(
|
||||
api.createLab(
|
||||
token(session),
|
||||
LabCreatePayload(
|
||||
number = number,
|
||||
title = title.trim(),
|
||||
number = form.number,
|
||||
title = form.title.trim(),
|
||||
deadlineAt =
|
||||
ru.ysu.lms.web.DateUtils
|
||||
.toUtcIso(deadlineAt),
|
||||
.toUtcIso(form.deadlineAt),
|
||||
defenseAt =
|
||||
ru.ysu.lms.web.DateUtils
|
||||
.toUtcIso(defenseAt),
|
||||
pointsMax = java.math.BigDecimal(pointsMax),
|
||||
status = status,
|
||||
descriptionMd = descriptionMd,
|
||||
.toUtcIso(form.defenseAt),
|
||||
pointsMax = java.math.BigDecimal(form.pointsMax),
|
||||
status = form.status,
|
||||
descriptionMd = form.descriptionMd,
|
||||
levels = levelList,
|
||||
),
|
||||
)
|
||||
@@ -285,18 +286,16 @@ class AdminLabController(
|
||||
@PostMapping("/labs/{labId}/levels/save")
|
||||
fun saveLevel(
|
||||
@PathVariable labId: String,
|
||||
@RequestParam(required = false) levelId: String?,
|
||||
@RequestParam code: String,
|
||||
@RequestParam title: String,
|
||||
@ModelAttribute form: SaveLevelForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
try {
|
||||
if (levelId.isNullOrBlank()) {
|
||||
api.addLevel(token(session), labId, LevelSavePayload(code, title))
|
||||
if (form.levelId.isNullOrBlank()) {
|
||||
api.addLevel(token(session), labId, LevelSavePayload(form.code, form.title))
|
||||
redirect.addFlashAttribute("notice", "Уровень добавлен")
|
||||
} else {
|
||||
api.renameLevel(token(session), labId, levelId, title)
|
||||
api.renameLevel(token(session), labId, form.levelId, form.title)
|
||||
redirect.addFlashAttribute("notice", "Уровень обновлён")
|
||||
}
|
||||
"redirect:/admin/labs/$labId"
|
||||
@@ -418,64 +417,45 @@ class AdminLabController(
|
||||
@PostMapping("/labs/{id}/edit")
|
||||
fun editLab(
|
||||
@PathVariable id: String,
|
||||
@RequestParam title: String,
|
||||
@RequestParam(required = false) deadlineAt: String?,
|
||||
@RequestParam(required = false) defenseAt: String?,
|
||||
@RequestParam pointsMax: String,
|
||||
@RequestParam status: String,
|
||||
@RequestParam descriptionMd: String,
|
||||
@RequestParam(defaultValue = "save") action: String,
|
||||
@RequestParam(required = false) levelIds: List<String>?,
|
||||
@RequestParam(required = false) levelTitles: List<String>?,
|
||||
@RequestParam(required = false) variantIds: List<String>?,
|
||||
@RequestParam(required = false) variantLevelIds: List<String>?,
|
||||
@RequestParam(required = false) variantNumbers: List<String>?,
|
||||
@RequestParam(required = false) variantTitles: List<String>?,
|
||||
@RequestParam(required = false) variantStatements: List<String>?,
|
||||
@RequestParam(required = false) newLevelCode: String?,
|
||||
@RequestParam(required = false) newLevelTitle: String?,
|
||||
@RequestParam(required = false) addLevelId: String?,
|
||||
@RequestParam(required = false) addNumber: String?,
|
||||
@RequestParam(required = false) addTitle: String?,
|
||||
@RequestParam(required = false) addStatementMd: String?,
|
||||
@ModelAttribute form: EditLabForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String {
|
||||
val t = token(session)
|
||||
return try {
|
||||
handleEditDeleteAction(t, id, action, redirect)?.let { return it }
|
||||
handleEditDeleteAction(t, id, form.action, redirect)?.let { return it }
|
||||
|
||||
api.updateLab(
|
||||
t,
|
||||
id,
|
||||
LabUpdatePayload(
|
||||
title,
|
||||
form.title,
|
||||
ru.ysu.lms.web.DateUtils
|
||||
.toUtcIso(deadlineAt),
|
||||
.toUtcIso(form.deadlineAt),
|
||||
ru.ysu.lms.web.DateUtils
|
||||
.toUtcIso(defenseAt),
|
||||
pointsMax,
|
||||
status,
|
||||
descriptionMd,
|
||||
.toUtcIso(form.defenseAt),
|
||||
form.pointsMax,
|
||||
form.status,
|
||||
form.descriptionMd,
|
||||
),
|
||||
)
|
||||
applyLevelRenames(t, id, levelIds, levelTitles)
|
||||
applyVariantSaves(t, id, variantIds, variantNumbers, variantLevelIds, variantTitles, variantStatements)
|
||||
applyLevelRenames(t, id, form.levelIds, form.levelTitles)
|
||||
applyVariantSaves(t, id, form.variantIds, form.variantNumbers, form.variantLevelIds, form.variantTitles, form.variantStatements)
|
||||
when {
|
||||
action == "add-level" && !newLevelCode.isNullOrBlank() && !newLevelTitle.isNullOrBlank() -> {
|
||||
api.addLevel(t, id, LevelSavePayload(newLevelCode.trim(), newLevelTitle.trim()))
|
||||
form.action == "add-level" && !form.newLevelCode.isNullOrBlank() && !form.newLevelTitle.isNullOrBlank() -> {
|
||||
api.addLevel(t, id, LevelSavePayload(form.newLevelCode.trim(), form.newLevelTitle.trim()))
|
||||
redirect.addFlashAttribute("notice", "Сохранено; уровень добавлен")
|
||||
}
|
||||
action == "add-variant" && !addLevelId.isNullOrBlank() && !addNumber.isNullOrBlank() -> {
|
||||
form.action == "add-variant" && !form.addLevelId.isNullOrBlank() && !form.addNumber.isNullOrBlank() -> {
|
||||
api.saveVariant(
|
||||
t,
|
||||
id,
|
||||
null,
|
||||
VariantSavePayload(
|
||||
addLevelId,
|
||||
addNumber.trim(),
|
||||
addTitle.orEmpty().trim(),
|
||||
addStatementMd.orEmpty(),
|
||||
form.addLevelId,
|
||||
form.addNumber.trim(),
|
||||
form.addTitle.orEmpty().trim(),
|
||||
form.addStatementMd.orEmpty(),
|
||||
),
|
||||
)
|
||||
redirect.addFlashAttribute("notice", "Сохранено; вариант добавлен")
|
||||
@@ -492,16 +472,17 @@ class AdminLabController(
|
||||
@PostMapping("/labs/{labId}/variants/save")
|
||||
fun saveVariant(
|
||||
@PathVariable labId: String,
|
||||
@RequestParam(required = false) variantId: String?,
|
||||
@RequestParam labLevelId: String,
|
||||
@RequestParam number: String,
|
||||
@RequestParam title: String,
|
||||
@RequestParam statementMd: String,
|
||||
@ModelAttribute form: SaveVariantForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
try {
|
||||
api.saveVariant(token(session), labId, variantId, VariantSavePayload(labLevelId, number, title, statementMd))
|
||||
api.saveVariant(
|
||||
token(session),
|
||||
labId,
|
||||
form.variantId,
|
||||
VariantSavePayload(form.labLevelId, form.number, form.title, form.statementMd),
|
||||
)
|
||||
redirect.addFlashAttribute("notice", "Вариант сохранён")
|
||||
"redirect:/admin/labs/$labId/edit"
|
||||
} catch (ex: ApiException) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.stereotype.Controller
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
@@ -66,11 +67,7 @@ class AdminStudentController(
|
||||
@PostMapping("/groups/{groupId}/students/create")
|
||||
fun createStudent(
|
||||
@PathVariable groupId: String,
|
||||
@RequestParam studentNo: String,
|
||||
@RequestParam lastName: String,
|
||||
@RequestParam(required = false) firstName: String?,
|
||||
@RequestParam(required = false) middleName: String?,
|
||||
@RequestParam(required = false) basis: String?,
|
||||
@ModelAttribute form: CreateStudentForm,
|
||||
session: HttpSession,
|
||||
redirect: RedirectAttributes,
|
||||
): String =
|
||||
@@ -80,11 +77,11 @@ class AdminStudentController(
|
||||
token(session),
|
||||
groupId,
|
||||
CreateStudentRequestDto(
|
||||
studentNo = studentNo.trim(),
|
||||
lastName = lastName.trim(),
|
||||
firstName = firstName.orEmpty().trim(),
|
||||
middleName = middleName.orEmpty().trim(),
|
||||
basis = basis.orEmpty().trim(),
|
||||
studentNo = form.studentNo.trim(),
|
||||
lastName = form.lastName.trim(),
|
||||
firstName = form.firstName.orEmpty().trim(),
|
||||
middleName = form.middleName.orEmpty().trim(),
|
||||
basis = form.basis.orEmpty().trim(),
|
||||
),
|
||||
)
|
||||
redirect.addFlashAttribute("createdStudent", result)
|
||||
|
||||
@@ -16,6 +16,7 @@ import ru.ysu.lms.web.api.ApiClient
|
||||
import ru.ysu.lms.web.api.ApiException
|
||||
import ru.ysu.lms.web.api.ArticlesReorderDto
|
||||
import ru.ysu.lms.web.api.ContentReorderDto
|
||||
import ru.ysu.lms.web.api.CreateArticlePayload
|
||||
import ru.ysu.lms.web.api.SectionsReorderDto
|
||||
import ru.ysu.lms.web.api.createArticle
|
||||
import ru.ysu.lms.web.api.createChapter
|
||||
@@ -269,12 +270,14 @@ class ContentAdminController(
|
||||
try {
|
||||
api.createArticle(
|
||||
token(session),
|
||||
form.chapterId,
|
||||
form.sectionId,
|
||||
form.newChapterTitle?.takeIf { it.isNotBlank() },
|
||||
form.newSectionTitle?.takeIf { it.isNotBlank() },
|
||||
form.title.trim(),
|
||||
form.bodyMd,
|
||||
CreateArticlePayload(
|
||||
chapterId = form.chapterId,
|
||||
sectionId = form.sectionId,
|
||||
newChapterTitle = form.newChapterTitle?.takeIf { it.isNotBlank() },
|
||||
newSectionTitle = form.newSectionTitle?.takeIf { it.isNotBlank() },
|
||||
title = form.title.trim(),
|
||||
bodyMd = form.bodyMd,
|
||||
),
|
||||
)
|
||||
redirect.addFlashAttribute("notice", "Статья «${form.title.trim()}» создана")
|
||||
redirectBack(form.back, "redirect:/admin/content")
|
||||
|
||||
@@ -231,14 +231,18 @@ fun ApiClient.deleteSectionWithMove(
|
||||
}
|
||||
}
|
||||
|
||||
data class CreateArticlePayload(
|
||||
val chapterId: String?,
|
||||
val sectionId: String?,
|
||||
val newChapterTitle: String?,
|
||||
val newSectionTitle: String?,
|
||||
val title: String,
|
||||
val bodyMd: String,
|
||||
)
|
||||
|
||||
fun ApiClient.createArticle(
|
||||
token: String,
|
||||
chapterId: String?,
|
||||
sectionId: String?,
|
||||
newChapterTitle: String?,
|
||||
newSectionTitle: String?,
|
||||
title: String,
|
||||
bodyMd: String,
|
||||
payload: CreateArticlePayload,
|
||||
): ContentArticleDto =
|
||||
call {
|
||||
client
|
||||
@@ -248,12 +252,12 @@ fun ApiClient.createArticle(
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(
|
||||
mapOf(
|
||||
"chapterId" to chapterId,
|
||||
"sectionId" to sectionId,
|
||||
"newChapterTitle" to newChapterTitle,
|
||||
"newSectionTitle" to newSectionTitle,
|
||||
"title" to title,
|
||||
"bodyMd" to bodyMd,
|
||||
"chapterId" to payload.chapterId,
|
||||
"sectionId" to payload.sectionId,
|
||||
"newChapterTitle" to payload.newChapterTitle,
|
||||
"newSectionTitle" to payload.newSectionTitle,
|
||||
"title" to payload.title,
|
||||
"bodyMd" to payload.bodyMd,
|
||||
),
|
||||
).retrieve()
|
||||
.body(ContentArticleDto::class.java)
|
||||
|
||||
Reference in New Issue
Block a user