diff --git a/backend/my_work/routers/apiQuiz.go b/backend/my_work/routers/apiQuiz.go index a273b93..4ede6bd 100644 --- a/backend/my_work/routers/apiQuiz.go +++ b/backend/my_work/routers/apiQuiz.go @@ -1431,6 +1431,31 @@ func ApiQuiz(r *gin.RouterGroup) { }) }) + // 删除本人的成绩记录(连带答题明细) + r.POST("/session/delete", func(ctx *gin.Context) { + isAuth, user, data := AuthenticationAuthority(ctx) + if !isAuth { + ReturnJson(ctx, "userCookieError", nil) + return + } + type FromDelete struct { + ID uint `json:"id"` + } + var from FromDelete + if err := decodeJSON(data, &from); err != nil || from.ID == 0 { + ReturnJson(ctx, "jsonErr", nil) + return + } + var session TabQuizSession + if err := models.DB.First(&session, from.ID).Error; err != nil || session.UserID != user.ID { + ReturnJson(ctx, "quiz_session_not_found", nil) + return + } + models.DB.Delete(&TabQuizAnswer{}, "session_id = ?", session.ID) + models.DB.Delete(&TabQuizSession{}, session.ID) + ReturnJson(ctx, "apiOK", nil) + }) + // 错题重做:仅判分,不写入任何数据 r.POST("/redo", func(ctx *gin.Context) { isAuth, user, data := AuthenticationAuthority(ctx) diff --git a/frontend/ops_vue_js/src/api/quiz.js b/frontend/ops_vue_js/src/api/quiz.js index ba6caf0..edcb4dd 100644 --- a/frontend/ops_vue_js/src/api/quiz.js +++ b/frontend/ops_vue_js/src/api/quiz.js @@ -53,6 +53,10 @@ export const quizApi = { mySessions(params = {}) { return api.post('/quiz/sessions', params) }, + /** 删除自己的成绩记录 */ + deleteSession(id) { + return api.post('/quiz/session/delete', { id }) + }, /** 答题回顾详情 */ getSession(id) { return api.post('/quiz/session', { id }) diff --git a/frontend/ops_vue_js/src/i18n/en.json b/frontend/ops_vue_js/src/i18n/en.json index 23698e9..1df05a2 100644 --- a/frontend/ops_vue_js/src/i18n/en.json +++ b/frontend/ops_vue_js/src/i18n/en.json @@ -883,7 +883,10 @@ "learn_title": "Study Mode", "learn_empty": "No questions in this bank yet", "loading_more": "Loading...", - "all_loaded": "All questions loaded" + "all_loaded": "All questions loaded", + "delete_record": "Delete", + "delete_record_title": "Delete Score Record", + "delete_record_confirm": "Delete this score record? This cannot be undone." }, "questions": { "title": "Question Bank", diff --git a/frontend/ops_vue_js/src/i18n/zh-CN.json b/frontend/ops_vue_js/src/i18n/zh-CN.json index 546a561..a6bba6f 100644 --- a/frontend/ops_vue_js/src/i18n/zh-CN.json +++ b/frontend/ops_vue_js/src/i18n/zh-CN.json @@ -884,7 +884,10 @@ "learn_title": "学习模式", "learn_empty": "该题库暂无题目", "loading_more": "加载中…", - "all_loaded": "已加载全部" + "all_loaded": "已加载全部", + "delete_record": "删除", + "delete_record_title": "删除成绩记录", + "delete_record_confirm": "确认删除该次成绩记录?删除后不可恢复。" }, "questions": { "title": "题库管理", diff --git a/frontend/ops_vue_js/src/views/quiz/QuestionList.vue b/frontend/ops_vue_js/src/views/quiz/QuestionList.vue index d87cd3e..b446bb3 100644 --- a/frontend/ops_vue_js/src/views/quiz/QuestionList.vue +++ b/frontend/ops_vue_js/src/views/quiz/QuestionList.vue @@ -20,8 +20,11 @@ import { IconChevronsLeft, IconChevronsRight, IconReload, + IconTrash, } from '@tabler/icons-vue' +import ConfirmDialog from '@/components/ConfirmDialog.vue' + usePageTitle('appname.quiz_bank') const { t, locale } = useI18n() const router = useRouter() @@ -176,6 +179,36 @@ function redoWrong(s) { router.push(`/quiz/redo/${s.id}`) } +// 删除本人成绩记录 +const delSessionTarget = ref(null) +const confirmDelSession = ref(false) + +function askDeleteSession(s) { + delSessionTarget.value = s + confirmDelSession.value = true +} + +async function doDeleteSession() { + if (!delSessionTarget.value) return + try { + const { errCode } = await quizApi.deleteSession(delSessionTarget.value.id) + if (errCode === 0) { + toast.success(t('message.delete_success')) + confirmDelSession.value = false + delSessionTarget.value = null + if (sessions.value.length === 1 && historyPage.value > 1) { + historyPage.value -= 1 + } + fetchSessions() + fetchBoard() + } else { + toast.error(t('message.server_error')) + } + } catch { + // 拦截器已处理 + } +} + // ── 排行榜 ── async function fetchBoard() { loadingBoard.value = true @@ -372,14 +405,23 @@ onMounted(() => {