feat(shared): add UI components, hooks, form fields, and action utils

- Add UI components: confirm-delete-dialog, empty-table-row, list-pagination, pagination, status-badge

- Add form-fields directory for reusable form field components

- Add hooks: use-action-mutation, use-action-query for server action integration

- Add action-utils lib for action state helpers

- Update a11y components, charts, global-search, onboarding-gate, question components

- Update UI components: chip-nav, filter-bar, page-header, stat-card, stat-item, switch, table

- Update hooks: use-action-with-toast, use-aria-live, use-debounce, use-local-storage, use-media-query, use-permission

- Update lib: a11y, ai, audit-logger, auth-guard, bcrypt-utils, change-logger, download, excel, file-storage, http-utils, login-logger, password-policy, password-security-service, permissions, rate-limit, role-utils, search-params, session, storage-provider

- Update types: action-state, permissions

- Update i18n messages (en, zh-CN) for dashboard, diagnostic, grades, lesson-preparation, settings
This commit is contained in:
SpecialX
2026-06-23 17:38:14 +08:00
parent 9ceb2b7b67
commit c4d3433cc9
25 changed files with 1986 additions and 28 deletions

View File

@@ -30,6 +30,17 @@
},
"list": {
"empty": "暂无成绩记录",
"caption": "成绩记录列表",
"deleteAriaLabel": "删除 {studentName} 的 {subjectName} 成绩记录",
"editAriaLabel": "编辑 {studentName} 的 {subjectName} 成绩记录",
"bulkDelete": "批量删除",
"bulkDeleteConfirmation": "确定要删除选中的 {count} 条成绩记录吗?此操作不可撤销。",
"bulkDeleteSelected": "已选中 {count} 条记录",
"bulkDeleteSuccess": "已删除 {count} 条成绩记录",
"bulkDeleteFailed": "批量删除失败",
"selectAll": "全选",
"selectRow": "选择 {name} 的成绩记录",
"clearSelection": "取消选择",
"columns": {
"student": "学生",
"class": "班级",
@@ -39,7 +50,8 @@
"type": "类型",
"semester": "学期",
"recordedBy": "录入人",
"date": "日期"
"date": "日期",
"actions": "操作"
}
},
"form": {
@@ -55,7 +67,9 @@
"fullScore": "满分",
"remark": "备注(可选)",
"remarkPlaceholder": "关于此成绩的备注...",
"selectPrompt": "请选择班级、科目和学生"
"selectPrompt": "请选择班级、科目和学生",
"student": "学生",
"titleLabel": "标题"
},
"delete": {
"title": "删除成绩记录",
@@ -64,11 +78,63 @@
"cancel": "取消",
"deleting": "删除中..."
},
"edit": {
"title": "编辑成绩记录",
"confirm": "保存修改",
"saving": "保存中...",
"cancel": "取消",
"score": "分数",
"fullScore": "满分",
"titleLabel": "标题",
"remark": "备注(可选)",
"remarkPlaceholder": "关于此成绩的备注...",
"success": "成绩记录已更新",
"failed": "更新失败"
},
"export": {
"detail": "导出成绩明细",
"classReport": "导出班级成绩总表",
"success": "导出成功",
"failed": "导出失败"
"failed": "导出失败",
"exporting": "导出中...",
"selectClassFirst": "请先选择班级",
"detailItem": "成绩明细",
"classReportItem": "班级成绩总表",
"defaultLabel": "导出",
"sheets": {
"detail": "成绩明细",
"summary": "统计汇总",
"classReport": "{className}_成绩总表"
},
"columns": {
"studentName": "学生姓名",
"class": "班级",
"subject": "科目",
"title": "标题",
"score": "分数",
"fullScore": "满分",
"type": "类型",
"semester": "学期",
"recorder": "录入人",
"remark": "备注",
"date": "录入日期",
"metric": "指标",
"value": "数值",
"total": "总分",
"average": "平均分",
"rank": "排名"
},
"metrics": {
"average": "均分",
"median": "中位数",
"max": "最高分",
"min": "最低分",
"stdDev": "标准差",
"passRate": "及格率(%)",
"excellentRate": "优秀率(%)",
"count": "参考人数",
"noData": "无数据"
}
},
"stats": {
"title": "统计",
@@ -80,7 +146,11 @@
"variance": "方差",
"passRate": "及格率",
"excellentRate": "优秀率",
"count": "人数"
"count": "人数",
"noData": "暂无统计数据。",
"stdDevHint": "标准差",
"passRateHint": "分数 ≥ 满分的 60%",
"excellentRateHint": "分数 ≥ 满分的 85%"
},
"analytics": {
"trend": "成绩趋势",
@@ -95,12 +165,22 @@
"averageScore": "平均分",
"passRate": "及格率",
"excellentRate": "优秀率",
"studentCount": "学生数"
"studentCount": "学生数",
"classComparisonLabel": "年级(用于班级对比)",
"allOption": "全部",
"semester": "学期",
"semesterAll": "全部学期",
"semester1": "第一学期",
"semester2": "第二学期",
"exam": "考试",
"examAll": "全部考试",
"noExams": "暂无关联考试"
},
"batch": {
"title": "批量录入",
"saving": "保存中...",
"restored": "已恢复未保存的成绩草稿",
"restoredFromServer": "已从服务端恢复成绩草稿(跨设备同步)",
"invalidScores": "存在无效分数",
"fullScoreRequired": "满分必填",
"saved": "已录入",
@@ -109,7 +189,45 @@
"fullScore": "满分",
"type": "类型",
"saveAll": "全部保存",
"cancel": "取消"
"cancel": "取消",
"saveAllGrades": "保存全部成绩",
"savingGrades": "保存成绩中...",
"selectClassAndSubject": "请选择班级和科目",
"invalidScoresError": "存在无效分数(超过满分或格式错误),请检查后重试",
"enterAtLeastOne": "请至少输入一个分数",
"noStudentsInClass": "该班级暂无学生。",
"entered": "已录入",
"average": "均分",
"max": "最高",
"min": "最低",
"searchStudent": "搜索学生...",
"examQuizTitle": "考试 / 测验标题",
"fullScoreHint": "满分 {max} 分。输入分数后按 Enter 跳到下一位学生。草稿每 30 秒自动保存2 小时内有效。",
"confirmSwitchClass": "当前班级有未保存的成绩记录,确认切换班级?",
"invalidScoresBadge": "存在无效分数",
"emailColumn": "邮箱",
"pasteApplied": "已从剪贴板粘贴 {count} 个分数",
"pasteNoMatch": "剪贴板内容无法识别为分数列",
"pasteHint": "提示:可从 Excel 复制一列分数粘贴到此处",
"undo": "撤销",
"undoNoRecord": "无可撤销的录入记录",
"undoExpired": "撤销已过期(超过 5 分钟)",
"undoFailed": "撤销失败,请重试",
"downloadTemplate": "下载模板",
"templateAriaLabel": "下载成绩录入模板",
"templateStudentName": "学生姓名",
"templateScore": "分数",
"templateRemark": "备注",
"templateFilename": "成绩录入模板.csv",
"guide": {
"title": "成绩录入指引",
"step1": "选择要录入成绩的班级和科目,填写考试或测验标题。",
"step2": "在分数列直接输入成绩,也可从 Excel 复制一列分数粘贴到此处。",
"step3": "系统每 30 秒自动保存草稿(本地 2 小时有效,服务端 24 小时跨设备同步)。",
"step4": "保存成功后可在 5 分钟内点击撤销按钮撤销本次录入。",
"dismiss": "知道了",
"dismissAriaLabel": "关闭录入指引"
}
},
"trend": {
"title": "成绩趋势",
@@ -118,12 +236,20 @@
"date": "日期"
},
"summary": {
"caption": "学生成绩汇总",
"title": "成绩摘要",
"averageScore": "平均分",
"classRank": "班级排名",
"rankValue": "第 {rank} 名",
"totalRecords": "总记录数",
"highestScore": "最高分",
"lowestScore": "最低分"
"lowestScore": "最低分",
"student": "学生",
"gradeHistory": "成绩历史",
"noGradesTitle": "暂无成绩",
"noGradesDescription": "该学生暂无成绩记录。",
"noDataTitle": "暂无数据",
"noDataDescription": "学生成绩摘要不可用。"
},
"empty": {
"noRecords": "暂无成绩记录",
@@ -139,5 +265,90 @@
"failedToCreate": "创建失败",
"failedToDelete": "删除失败",
"retry": "重试"
},
"widget": {
"error": "组件加载失败",
"retry": "重试",
"loading": "加载中...",
"block": "区块",
"loadFailed": "{title}加载失败",
"defaultFallback": "请重试或刷新页面",
"retryAriaLabel": "重试加载{title}",
"loadingAriaLabel": "{title}加载中"
},
"chart": {
"scorePercent": "分数 (%)",
"students": "学生数",
"averagePercent": "平均分 (%)",
"passRatePercent": "及格率 (%)",
"excellentPercent": "优秀率 (%)",
"average": "平均分",
"passRate": "及格率",
"classAverage": "班级平均"
},
"distribution": {
"title": "分数分布",
"descriptionEmpty": "每个分数区间内的学生人数(标准化为 0-100。",
"descriptionNonEmpty": "{count} 条成绩记录分布在各分数区间。",
"emptyTitle": "暂无分布数据",
"emptyDescription": "请选择班级和科目查看分数分布。",
"ariaLabelEmpty": "分数分布柱状图:暂无数据",
"ariaLabelNonEmpty": "分数分布柱状图:共 {count} 条成绩记录分布在 5 个分数区间",
"tooltipStudents": "{count} 名学生",
"tooltipOfTotal": "占总数的 {percentage}%"
},
"subjectComparison": {
"descriptionEmpty": "对比所选班级各科目的表现。",
"descriptionNonEmpty": "各科目的平均分和及格率(标准化为 0-100。",
"emptyTitle": "暂无对比数据",
"emptyDescription": "请选择班级对比科目表现。",
"ariaLabelEmpty": "科目对比雷达图:暂无数据",
"ariaLabelNonEmpty": "科目对比雷达图:共 {count} 个科目的均分与及格率对比"
},
"classComparison": {
"descriptionEmpty": "对比各班级的平均分、及格率和优秀率。",
"descriptionNonEmpty": "各班级的平均分、及格率≥60%和优秀率≥85%)。",
"emptyTitle": "暂无对比数据",
"emptyDescription": "请选择年级和科目对比班级。",
"ariaLabelEmpty": "班级对比柱状图:暂无数据",
"ariaLabelNonEmpty": "班级对比柱状图:共 {count} 个班级的均分、及格率与优秀率对比",
"significanceTitle": "显著性分析",
"significanceRange": "班级间最大差异为 {range} 分",
"significanceHigh": "差异显著",
"significanceMedium": "可能存在差异",
"significanceLow": "差异不显著",
"significanceHighHint": "极差较大且各班样本量充足≥30班级间表现差异具有统计意义。",
"significanceMediumHint": "存在一定差异,但可能受样本量或随机波动影响,建议进一步分析。",
"significanceLowHint": "极差较小,班级间表现接近,差异不具统计意义。",
"significanceAriaLabel": "显著性分析:{level}",
"significanceDetails": "查看详细分析",
"significanceTopClass": "最高分班级:{name}{score} 分)",
"significanceBottomClass": "最低分班级:{name}{score} 分)"
},
"trendChart": {
"descriptionEmpty": "随时间变化的分数趋势(标准化为 0-100。",
"descriptionNonEmpty": "{label} · 平均 {average}%",
"emptyTitle": "暂无趋势数据",
"emptyDescription": "请选择班级和科目查看成绩趋势。",
"ariaLabelEmpty": "成绩趋势图:暂无数据",
"ariaLabelNonEmpty": "成绩趋势图:{label},平均 {average}%"
},
"trendCard": {
"emptyDescription": "添加成绩记录后,成绩趋势将显示在此处。",
"ariaLabelEmpty": "成绩趋势图:暂无数据",
"ariaLabelNonEmpty": "成绩趋势图:共 {count} 次成绩记录",
"rangeAriaLabel": "选择日期范围"
},
"rankingTrend": {
"ariaLabelEmpty": "排名趋势图:暂无数据",
"ariaLabelNonEmpty": "排名趋势图:共 {count} 次排名记录"
},
"classReport": {
"noDataTitle": "暂无数据",
"noDataDescription": "该班级暂无成绩记录。",
"classRanking": "班级排名",
"rankColumn": "排名",
"recordsColumn": "记录数",
"studentCountInfo": "{studentCount} 名学生 · {recordCount} 条成绩记录"
}
}