Files
NextEdu/src/app/(dashboard)/dashboard/page.tsx
SpecialX 868ac5f9cf 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 / 文件清单)
2026-06-22 15:50:56 +08:00

29 lines
952 B
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { redirect } from "next/navigation"
import { auth } from "@/auth"
import { Permissions } from "@/shared/types/permissions"
import { resolvePermissions } from "@/shared/lib/permissions"
import { isRole } from "@/shared/types/permissions"
export const dynamic = "force-dynamic"
export default async function DashboardPage(): Promise<void> {
const session = await auth()
if (!session?.user) redirect("/login")
const roles = (session.user.roles ?? []).filter(isRole)
const permissions = resolvePermissions(roles)
// 按优先级匹配仪表盘权限admin > student > parent > teacher
if (permissions.includes(Permissions.DASHBOARD_ADMIN_READ)) {
redirect("/admin/dashboard")
}
if (permissions.includes(Permissions.DASHBOARD_STUDENT_READ)) {
redirect("/student/dashboard")
}
if (permissions.includes(Permissions.DASHBOARD_PARENT_READ)) {
redirect("/parent/dashboard")
}
redirect("/teacher/dashboard")
}