feat(dashboard): 仪表盘模块审计重构 — 权限校验 + i18n + 逻辑抽离
基于 dashboard-audit-report.md 审计结论,对仪表盘模块进行 P0/P1 级修复:
- 新增 4 个 dashboard 权限点(DASHBOARD_ADMIN/TEACHER/STUDENT/PARENT_READ),补充到 permissions.ts 和角色-权限映射
- 新建 actions.ts:4 个 Server Action 均调用 requirePermission() 校验权限,消除 admin 页面零鉴权、teacher/student/parent 仅 requireAuth 的安全隐患
- 根重定向页 /dashboard 改用 resolvePermissions() + 权限点判断,不再 role === xxx 硬编码
- 新建 lib/dashboard-utils.ts:抽取 toWeekday / countStudentAssignments / sortUpcomingAssignments / filterTodaySchedule / computeTeacherMetrics / getGreetingKey 纯函数,与 UI 分离,便于单测
- 新建 messages/{zh-CN,en}/dashboard.json 翻译文件,i18n request.ts 加载 dashboard 命名空间;所有视图组件接入 useTranslations / getTranslations,消除中英混杂硬编码
- 重构 4 个角色 page.tsx:通过 actions 获取数据,generateMetadata 使用 i18n
- 同步更新架构图 004 / 005 文档(dashboard exports / permissions / 文件清单)
This commit is contained in:
@@ -121,7 +121,11 @@
|
||||
"LESSON_PLAN_READ": "lesson_plan:read",
|
||||
"LESSON_PLAN_UPDATE": "lesson_plan:update",
|
||||
"LESSON_PLAN_DELETE": "lesson_plan:delete",
|
||||
"LESSON_PLAN_PUBLISH": "lesson_plan:publish"
|
||||
"LESSON_PLAN_PUBLISH": "lesson_plan:publish",
|
||||
"DASHBOARD_ADMIN_READ": "dashboard:admin_read",
|
||||
"DASHBOARD_TEACHER_READ": "dashboard:teacher_read",
|
||||
"DASHBOARD_STUDENT_READ": "dashboard:student_read",
|
||||
"DASHBOARD_PARENT_READ": "dashboard:parent_read"
|
||||
},
|
||||
"rolePermissions": {
|
||||
"admin": [
|
||||
@@ -176,7 +180,8 @@
|
||||
"ELECTIVE_MANAGE",
|
||||
"ELECTIVE_READ",
|
||||
"EXAM_PROCTOR",
|
||||
"EXAM_PROCTOR_READ"
|
||||
"EXAM_PROCTOR_READ",
|
||||
"DASHBOARD_ADMIN_READ"
|
||||
],
|
||||
"teacher": [
|
||||
"EXAM_CREATE",
|
||||
@@ -216,7 +221,8 @@
|
||||
"ELECTIVE_MANAGE",
|
||||
"ELECTIVE_READ",
|
||||
"EXAM_PROCTOR",
|
||||
"EXAM_PROCTOR_READ"
|
||||
"EXAM_PROCTOR_READ",
|
||||
"DASHBOARD_TEACHER_READ"
|
||||
],
|
||||
"student": [
|
||||
"EXAM_READ",
|
||||
@@ -236,7 +242,8 @@
|
||||
"MESSAGE_DELETE",
|
||||
"DIAGNOSTIC_READ",
|
||||
"ELECTIVE_SELECT",
|
||||
"ELECTIVE_READ"
|
||||
"ELECTIVE_READ",
|
||||
"DASHBOARD_STUDENT_READ"
|
||||
],
|
||||
"parent": [
|
||||
"EXAM_READ",
|
||||
@@ -248,7 +255,8 @@
|
||||
"ATTENDANCE_READ",
|
||||
"MESSAGE_SEND",
|
||||
"MESSAGE_READ",
|
||||
"MESSAGE_DELETE"
|
||||
"MESSAGE_DELETE",
|
||||
"DASHBOARD_PARENT_READ"
|
||||
],
|
||||
"grade_head": [
|
||||
"EXAM_CREATE",
|
||||
@@ -5724,8 +5732,96 @@
|
||||
},
|
||||
"dashboard": {
|
||||
"path": "src/modules/dashboard",
|
||||
"description": "各角色仪表盘数据聚合与展示",
|
||||
"description": "各角色仪表盘数据聚合与展示(含权限校验 + i18n + 纯逻辑工具函数)",
|
||||
"exports": {
|
||||
"actions": [
|
||||
{
|
||||
"name": "getAdminDashboardAction",
|
||||
"signature": "() => Promise<AdminDashboardData>",
|
||||
"deps": [
|
||||
"shared/lib/auth-guard.requirePermission",
|
||||
"dashboard/data-access.getAdminDashboardData",
|
||||
"Permissions.DASHBOARD_ADMIN_READ"
|
||||
],
|
||||
"usedBy": [
|
||||
"admin/dashboard/page.tsx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getTeacherDashboardAction",
|
||||
"signature": "() => Promise<TeacherDashboardData & { metrics: TeacherDashboardMetrics }>",
|
||||
"deps": [
|
||||
"shared/lib/auth-guard.requirePermission",
|
||||
"classes/data-access.getTeacherClasses/getClassSchedule/getTeacherIdForMutations",
|
||||
"homework/data-access.getHomeworkAssignments/getHomeworkSubmissions/getTeacherGradeTrends",
|
||||
"users/data-access.getUserBasicInfo",
|
||||
"dashboard/lib/dashboard-utils.computeTeacherMetrics",
|
||||
"Permissions.DASHBOARD_TEACHER_READ"
|
||||
],
|
||||
"usedBy": [
|
||||
"teacher/dashboard/page.tsx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getStudentDashboardAction",
|
||||
"signature": "() => Promise<{ student, dashboardProps }>",
|
||||
"deps": [
|
||||
"shared/lib/auth-guard.requirePermission",
|
||||
"users/data-access.getCurrentStudentUser",
|
||||
"classes/data-access.getStudentClasses/getStudentSchedule",
|
||||
"homework/data-access.getStudentHomeworkAssignments/getStudentDashboardGrades",
|
||||
"dashboard/lib/dashboard-utils.countStudentAssignments/sortUpcomingAssignments/toWeekday/filterTodaySchedule",
|
||||
"Permissions.DASHBOARD_STUDENT_READ"
|
||||
],
|
||||
"usedBy": [
|
||||
"student/dashboard/page.tsx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "getParentDashboardAction",
|
||||
"signature": "() => Promise<{ data, hasChildren }>",
|
||||
"deps": [
|
||||
"shared/lib/auth-guard.requirePermission",
|
||||
"parent/data-access.getParentDashboardData",
|
||||
"Permissions.DASHBOARD_PARENT_READ"
|
||||
],
|
||||
"usedBy": [
|
||||
"parent/dashboard/page.tsx"
|
||||
]
|
||||
}
|
||||
],
|
||||
"lib": [
|
||||
{
|
||||
"name": "toWeekday",
|
||||
"signature": "(d: Date) => Weekday",
|
||||
"purpose": "Date 转 1-7 周几(周一=1,周日=7)"
|
||||
},
|
||||
{
|
||||
"name": "countStudentAssignments",
|
||||
"signature": "(assignments, now, dueSoonWindowDays?) => StudentAssignmentStats",
|
||||
"purpose": "单次遍历统计学生作业:即将到期/已逾期/已批改"
|
||||
},
|
||||
{
|
||||
"name": "sortUpcomingAssignments",
|
||||
"signature": "(assignments, limit?) => StudentHomeworkAssignmentListItem[]",
|
||||
"purpose": "按截止日期升序排序取前 N 条"
|
||||
},
|
||||
{
|
||||
"name": "filterTodaySchedule",
|
||||
"signature": "(schedule, weekday, classNameById?) => StudentTodayScheduleItem[] | TeacherTodayScheduleItem[]",
|
||||
"purpose": "筛选指定周几课表并按开始时间排序"
|
||||
},
|
||||
{
|
||||
"name": "computeTeacherMetrics",
|
||||
"signature": "(classes, schedule, assignments, submissions, gradeTrends, now) => TeacherDashboardMetrics",
|
||||
"purpose": "计算教师仪表盘派生指标:待批改数/进行中作业/平均分/提交率/今日课表/待批改列表"
|
||||
},
|
||||
{
|
||||
"name": "getGreetingKey",
|
||||
"signature": "(now: Date) => 'morning' | 'afternoon' | 'evening'",
|
||||
"purpose": "根据当前小时返回问候语时段 key"
|
||||
}
|
||||
],
|
||||
"dataAccess": [
|
||||
{
|
||||
"name": "getAdminDashboardData",
|
||||
@@ -5740,7 +5836,7 @@
|
||||
"DataScope"
|
||||
],
|
||||
"usedBy": [
|
||||
"admin/dashboard/page.tsx"
|
||||
"dashboard/actions.getAdminDashboardAction"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user