feat(exam-homework): add audit report, i18n, error boundaries, and permission hardening

- Add comprehensive audit report for exam and homework module

- Create exam-homework i18n message files (zh-CN + en) and register namespace

- Add permission check to gradeHomeworkSubmissionAction to prevent horizontal privilege escalation

- Add Error Boundary + loading.tsx for 5 key pages (exam build/proctoring, homework assignment/submissions, student assignment)

- Refactor exam-columns to createExamColumns(t) factory for i18n support

- Refactor exam-data-table to manage columns internally via useTranslations

- Replace hardcoded strings with i18n keys in all exam/homework components and pages

- Add getHomeworkSubmissionForGrading data-access for secure grading flow
This commit is contained in:
SpecialX
2026-06-22 16:08:39 +08:00
parent fde711ce46
commit 21c7e65fee
26 changed files with 2059 additions and 463 deletions

View File

@@ -0,0 +1,352 @@
{
"exam": {
"list": {
"title": "考试列表",
"create": "创建考试",
"empty": "暂无考试",
"emptyFiltered": "没有匹配筛选条件的考试",
"emptyDescription": "创建第一份考试,开始布置与批改。",
"emptyFilteredDescription": "尝试清除筛选条件或调整关键词。",
"clearFilters": "清除筛选",
"showing": "显示",
"examsUnit": "份考试",
"searchPlaceholder": "搜索考试..."
},
"form": {
"createTitle": "创建考试",
"createDescription": "为班级配置一份新考试。",
"buildTitle": "组卷",
"buildDescription": "为考试组装题目。",
"title": "考试标题",
"subject": "科目",
"grade": "年级",
"difficulty": "难度",
"totalScore": "总分",
"durationMin": "考试时长(分钟)",
"scheduledAt": "计划时间",
"questions": "题目",
"missingSubjectOrGrade": "缺少科目或年级配置",
"previewBeforeCreate": "请先预览并确认后再创建",
"createSuccess": "考试草稿已创建",
"redirecting": "正在跳转到组卷页...",
"createFailed": "创建考试失败",
"loadFormFailed": "加载表单数据失败",
"loadSubjectsFailed": "加载科目失败",
"loadGradesFailed": "加载年级失败"
},
"status": {
"draft": "草稿",
"published": "已发布",
"archived": "已归档"
},
"difficulty": {
"1": "简单",
"2": "偏易",
"3": "中等",
"4": "偏难",
"5": "困难"
},
"actions": {
"preview": "预览考试",
"copyId": "复制 ID",
"edit": "编辑",
"build": "组卷",
"duplicate": "复制",
"publish": "发布",
"moveToDraft": "移至草稿",
"archive": "归档",
"delete": "删除",
"deleteConfirmTitle": "确定要删除吗?",
"deleteConfirmDescription": "此操作不可撤销。将永久删除考试\"{{title}}\"及所有关联数据。",
"cancel": "取消",
"deleteSuccess": "考试已删除",
"deleteFailed": "删除考试失败",
"publishSuccess": "考试已发布",
"archiveSuccess": "考试已归档",
"draftSuccess": "考试已移至草稿",
"duplicateSuccess": "考试已复制",
"duplicateFailed": "复制考试失败",
"updateFailed": "更新考试失败",
"previewFailed": "加载考试预览失败",
"idCopied": "考试 ID 已复制",
"openMenu": "打开菜单",
"selectRow": "选择行",
"selectAll": "全选",
"noQuestions": "此考试暂无题目。",
"loadingPreview": "正在加载预览..."
},
"columns": {
"examInfo": "考试信息",
"status": "状态",
"stats": "统计",
"difficulty": "难度",
"date": "日期",
"scheduled": "已计划",
"created": "创建于",
"questions": "题",
"points": "分"
},
"filters": {
"status": "状态",
"anyStatus": "任意状态",
"difficulty": "难度",
"anyDifficulty": "任意难度"
},
"error": {
"notFound": "考试不存在",
"loadFailed": "加载考试失败"
}
},
"homework": {
"list": {
"title": "作业列表",
"description": "管理作业,查看提交率与批改进度。",
"create": "创建作业",
"empty": "暂无作业",
"emptyFiltered": "该班级还没有作业。",
"emptyDescription": "您还没有创建任何作业。",
"clearFilters": "清除筛选",
"filterByClass": "按班级筛选:{{className}}",
"columns": {
"title": "标题",
"status": "状态",
"dueAt": "截止时间",
"submissionRate": "提交率",
"averageScore": "平均分",
"overdue": "逾期",
"sourceExam": "来源考试",
"createdAt": "创建时间"
},
"pagination": {
"itemLabel": "个作业"
}
},
"form": {
"createTitle": "创建作业",
"quickMode": "快速作业",
"quickModeDescription": "直接输入标题和描述,无需建题",
"examMode": "考试派生作业",
"examModeDescription": "从已有考试派生作业",
"class": "班级",
"selectClass": "选择班级",
"sourceExam": "来源考试",
"selectExam": "选择考试",
"assignmentTitle": "作业标题",
"titlePlaceholderQuick": "例如:背诵第三课课文",
"titlePlaceholderExam": "默认使用考试标题",
"description": "描述(可选)",
"descriptionPlaceholderQuick": "输入作业要求、题目内容或说明...",
"availableAt": "开放时间(可选)",
"dueAt": "截止时间(可选)",
"allowLate": "允许迟交",
"lateDueAt": "迟交截止时间(可选)",
"maxAttempts": "最大尝试次数",
"submit": "创建作业",
"submitting": "创建中...",
"creating": "正在创建作业...",
"selectExamRequired": "请选择考试",
"titleRequired": "请输入标题",
"selectClassRequired": "请选择班级",
"createSuccess": "作业已创建",
"createFailed": "创建失败"
},
"take": {
"questions": "题目",
"question": "第 {{index}} 题",
"points": "分",
"startAssignment": "开始作答",
"submitAssignment": "提交作业",
"submitAll": "全部提交",
"saveAnswer": "保存答案",
"saved": "已保存",
"saveFailed": "保存失败",
"starting": "正在开始...",
"submitting": "正在提交...",
"started": "已开始",
"submitted": "已提交",
"notStarted": "未开始",
"readyToStart": "准备好开始了吗?",
"readyDescription": "点击上方\"开始作答\"按钮。点击\"保存答案\"将保存您的答案。",
"startNow": "立即开始",
"back": "返回",
"confirmSubmit": "确认提交",
"confirmSubmitDescription": "所有题目已作答。提交后答案不可修改,确定要提交吗?",
"unansweredWarning": "您有 {{count}} 道题未作答。提交后答案不可修改,确定要提交吗?",
"cancel": "取消",
"confirmSubmitAction": "确认提交",
"submitSuccess": "已提交",
"submitFailed": "提交失败",
"startSuccess": "已开始",
"startFailed": "开始失败",
"assignmentInfo": "作业信息",
"status": "状态",
"dueDate": "截止时间",
"overdue": "已逾期",
"hoursLeft": "还剩 {{hours}} 小时",
"lessThanOneHour": "不足 1 小时",
"attempts": "尝试次数",
"attemptsUsed": "已用 {{used}} / {{max}}",
"attemptsRemaining": "· 剩余 {{remaining}} 次",
"description": "描述",
"noDescription": "无描述。",
"progress": "进度",
"jumpToQuestion": "跳转到第 {{index}} 题",
"yourAnswer": "你的答案",
"answerPlaceholder": "在此输入答案...",
"true": "正确",
"false": "错误",
"unsupportedType": "不支持的题型",
"teacherFeedback": "教师反馈",
"noFeedback": "无具体反馈。",
"makeSureAnswered": "请确保已作答所有题目。"
},
"grade": {
"title": "批改",
"submissions": "提交记录",
"student": "学生",
"status": "状态",
"submitted": "提交时间",
"score": "分数",
"action": "操作",
"back": "返回",
"openAssignment": "打开作业",
"late": "迟交",
"targets": "应交",
"submittedCount": "已交",
"gradedCount": "已改",
"exam": "考试",
"gradingSummary": "批改摘要",
"totalScore": "总分",
"correct": "正确",
"incorrect": "错误",
"partial": "部分正确",
"questionStatus": "题目状态",
"studentAnswer": "学生答案",
"referenceAnswer": "参考答案",
"noReferenceAnswer": "无参考答案。",
"noQuestionText": "无题目文本",
"autoGraded": "自动判分",
"correctButton": "正确",
"incorrectButton": "错误",
"scoreLabel": "分数",
"addFeedback": "添加反馈",
"hideFeedback": "隐藏反馈",
"feedbackPlaceholder": "为 {{name}} 添加反馈...",
"submitGrades": "提交成绩",
"saving": "保存中...",
"gradesSaved": "批改已保存",
"gradesSaveFailed": "保存批改失败",
"previousStudent": "上一名学生",
"nextStudent": "下一名学生",
"prev": "上一页",
"next": "下一页",
"gradesAutoSaveNote": "点击提交后成绩将自动保存。学生将在您提交后立即看到成绩和反馈。"
},
"review": {
"title": "复习",
"yourAnswer": "你的答案",
"correctAnswer": "正确答案",
"teacherFeedback": "教师反馈",
"score": "得分",
"maxScore": "满分"
},
"status": {
"draft": "草稿",
"published": "已发布",
"archived": "已归档",
"started": "进行中",
"submitted": "已提交",
"graded": "已批改",
"not_started": "未开始",
"in_progress": "进行中"
},
"error": {
"notFound": "作业不存在",
"submissionNotFound": "提交记录不存在",
"unauthorized": "无权限",
"submissionLocked": "提交已锁定",
"pastDue": "已过截止时间",
"pastLateDue": "已过迟交截止时间",
"noActiveStudents": "该班级没有活跃学生",
"classNotFound": "班级不存在",
"examNotFound": "考试不存在",
"examSubjectNotSet": "考试未设置科目",
"notAssignedToClass": "未分配到该班级",
"notAssignedToSubject": "未分配到该科目",
"notAssigned": "未分配该作业",
"notAvailableYet": "作业尚未开放",
"noAttemptsLeft": "尝试次数已用完",
"assignmentNotFound": "作业不存在",
"assignmentNotAvailable": "作业不可用"
}
},
"proctoring": {
"mode": {
"title": "考试模式",
"description": "选择考试模式并配置相关选项。监考模式会启用防作弊监控。",
"homework": "作业模式",
"timed": "限时模式",
"proctored": "监考模式",
"homeworkDescription": "学生可在任意时间作答,无时间限制",
"timedDescription": "限时作答,到时自动提交",
"proctoredDescription": "限时作答 + 防作弊监控 + 强制全屏"
},
"config": {
"duration": "考试时长(分钟)",
"durationTimedDescription": "学生开始作答后,到时自动提交",
"durationProctoredDescription": "监考模式下必须设置考试时长",
"shuffleQuestions": "题目乱序",
"shuffleQuestionsDescription": "每位学生看到的题目顺序随机",
"antiCheat": "启用防作弊监控",
"antiCheatDescription": "监听切屏、复制、右键、开发者工具等异常行为",
"allowLateStart": "允许迟开始",
"allowLateStartDescription": "允许学生在考试开始后一段时间内进入",
"lateStartGrace": "迟到宽限时间(分钟)",
"lateStartGraceDescription": "超过此时间后不允许新学生进入"
},
"dashboard": {
"title": "监考面板",
"summary": "摘要",
"students": "学生",
"recentEvents": "最近事件",
"noEvents": "暂无事件",
"eventCount": "事件数",
"abnormalCount": "异常数"
},
"events": {
"tab_switch": "切换标签页",
"window_blur": "窗口失焦",
"copy_attempt": "复制尝试",
"paste_attempt": "粘贴尝试",
"right_click": "右键点击",
"devtools_open": "开发者工具",
"fullscreen_exit": "退出全屏",
"idle_timeout": "空闲超时"
}
},
"common": {
"loading": "加载中...",
"save": "保存",
"cancel": "取消",
"confirm": "确认",
"back": "返回",
"edit": "编辑",
"delete": "删除",
"create": "创建",
"search": "搜索",
"filter": "筛选",
"noResults": "无结果",
"error": "错误",
"success": "成功",
"failed": "失败",
"retry": "重试",
"page": "页",
"of": "共",
"selected": "已选",
"rows": "行",
"view": "查看",
"continue": "继续",
"other": "其他",
"completed": "已完成"
}
}