- Update architecture impact map, data, feature checklist, gap audit - Add audit reports for dashboard, exam-homework, grades-diagnostic, settings-profile, textbooks - Update bug reports (admin, teacher, lesson-preparation, others, shared) - Update coding standards, DR plan, design docs, and README
33 KiB
前端功能模块与用户体验深度审查报告 v4
审查范围:
src/app/(dashboard)/{announcements,dashboard,management,messages,profile,settings}及相关modules/*/components审查维度:功能模块合理性、页面布局、用户使用习惯、同类产品对比、缺陷与不足 审查日期:2026-06-20 审查方法:5 个子代理并行深度审查 + 同类产品对比分析
一、总体结论
本次审查覆盖 6 大模块、50+ 页面、100+ 组件,共发现 201 个问题,分布如下:
| 严重程度 | 数量 | 占比 |
|---|---|---|
| P0(阻断/安全) | 14 | 7% |
| P1(重要功能缺失) | 52 | 26% |
| P2(体验/功能不完整) | 81 | 40% |
| P3(优化建议) | 54 | 27% |
核心发现
- 安全漏洞集中爆发:14 个 P0 问题中有 12 个是权限校验缺失,涉及 admin 下几乎所有页面,任何登录用户可访问管理后台数据
- 功能完整性严重不足:消息模块处于 MVP 阶段,缺草稿/群发/搜索/附件/实时推送;公告模块定向推送完全失效;设置模块缺 2FA/登录历史/设备管理
- 用户体验与同类产品差距显著:对比钉钉/企业微信/飞书/Google Classroom/PowerSchool,在实时性、批量操作、搜索筛选、数据可视化等方面全面落后
- 中英文混排严重:管理后台页面标题中文、组件 UI 英文、注释中文,缺乏统一 i18n 策略
- 基础设施缺失:大量路由缺少 loading.tsx/error.tsx,列表页缺少分页/搜索/批量操作
二、Dashboard 仪表盘模块(31 个问题)
2.1 P0 严重问题(4 个)
D-P0-1 多角色用户重定向逻辑存在优先级冲突
- 文件:
src/app/(dashboard)/dashboard/page.tsx第 10-15 行 - 问题:用户同时拥有多角色(如 admin+teacher)时,按
admin → student → parent → teacher硬编码优先级重定向,用户无法选择以其他角色进入。app-sidebar.tsx第 35-42 行同样逻辑重复 - 同类对比:钉钉/企业微信均支持角色切换器
- 改进建议:SiteHeader 增加角色切换下拉菜单,所选角色持久化到 cookie
- 严重程度:P0
D-P0-2 StudentStatsGrid 接收的 props 与实际渲染不一致
- 文件:
src/modules/dashboard/components/student-dashboard/student-stats-grid.tsx第 6-16 行 - 问题:组件声明 5 个 props(enrolledClassCount、dueSoonCount、overdueCount、gradedCount、ranking),但只渲染 3 个。
enrolledClassCount和gradedCount完全未使用,学生仪表盘缺失"已选课程数"和"已评分作业数" - 改进建议:补全 4 个 StatCard 渲染
- 严重程度:P0
D-P0-3 Teacher/Parent 仪表盘缺少 loading.tsx 和 error.tsx
- 文件:
src/app/(dashboard)/teacher/dashboard/、src/app/(dashboard)/parent/dashboard/、src/app/(dashboard)/dashboard/三个目录 - 问题:对比 student/dashboard 有 loading.tsx,teacher/parent 仪表盘在网络慢或数据加载失败时白屏。teacher/dashboard 并行请求 6 个数据源,任一失败整页崩溃
- 改进建议:三个目录各添加 loading.tsx(骨架屏)和 error.tsx(错误边界+重试)
- 严重程度:P0
D-P0-4 TeacherDashboardHeader 硬编码"Good morning"问候语
- 文件:
src/modules/dashboard/components/teacher-dashboard/teacher-dashboard-header.tsx第 18 行 - 问题:标题始终显示
Good morning,未根据时间动态切换。而 student-dashboard-header.tsx 第 9-13 行和 parent-dashboard.tsx 第 13-17 行都正确实现了按时段问候 - 改进建议:复用 student 的问候逻辑,抽取到
shared/lib/greeting.ts - 严重程度:P0
2.2 P1 重要问题(7 个)
| 编号 | 文件 | 问题 | 改进建议 |
|---|---|---|---|
| D-P1-1 | admin-dashboard.tsx 第 13-31 行 | AdminDashboard 缺少快捷操作入口(创建用户/发公告/调课表) | PageHeader actions 增加 Button |
| D-P1-2 | admin-dashboard.tsx 全文 | 缺少"待办事项""系统健康""今日关键事件""最近登录日志"模块 | 增加 Pending Approvals 和 System Health 卡片 |
| D-P1-3 | teacher-dashboard-view.tsx 第 36-42 行 | 未清理的注释和 a.submittedAt! 非空断言违反项目规则 |
清理注释,改为显式过滤 |
| D-P1-4 | student-dashboard-view.tsx 第 31-39 行 | Student 仪表盘布局比例失衡,col-span 嵌套混乱,缺少课程进度/出勤率/学习时长 | 修正 col-span,增加 Attendance Summary 卡片 |
| D-P1-5 | parent-dashboard.tsx 全文 | Parent 仪表盘缺少多子女对比视图、学校通知摘要、家长会预约、子女今日课表 | 增加 "Today at a Glance" 聚合区域 |
| D-P1-6 | app-sidebar.tsx 第 35-42 行 vs dashboard/page.tsx 第 12-15 行 | 角色判断逻辑重复且 fallback 到 teacher 导航可能展示无权限菜单 | 抽取 getPrimaryRole 工具函数,fallback 返回空数组 |
| D-P1-7 | site-header.tsx 第 70 行 | 面包屑过滤基于 title 而非 segment,逻辑脆弱 | 改为基于 segment 过滤 |
2.3 P2/P3 问题(20 个,略)
详见子报告,主要包括:col-span 冲突、ScrollArea 固定高度违反任意值规则、animate-pulse 可访问性、Avatar src 硬编码 undefined、metadata 不一致、toWeekday 函数重复、空状态文案语言不一致、缺少 focus-visible 样式、status 未本地化、缺少返回顶部、移动端搜索隐藏、表格无横向滚动、无数据刷新机制等。
2.4 同类产品对比
| 功能 | Google Classroom | 钉钉教育 | PowerSchool | 本项目 | 差距 |
|---|---|---|---|---|---|
| 首屏待办聚合 | ✅ | ✅ | ✅ | 部分角色有 | Parent 缺失 |
| 快速创建按钮 | ✅ "+" 浮动 | ✅ | ✅ | 仅 Teacher | Admin/Student 缺失 |
| 多子女对比 | N/A | ✅ | ✅ | ❌ | 缺失 |
| 出勤率热力图 | ❌ | ✅ | ✅ | ❌ | 缺失 |
| 数据大屏 | ❌ | ✅ | ✅ | 基础统计 | 不如图表化 |
| 课表打印 | ❌ | ✅ | ✅ | ❌ | 缺失 |
三、Announcements 公告模块(31 个问题)
3.1 P0 严重问题(4 个)
A-P0-1 管理端列表页缺失权限校验
- 文件:
src/app/(dashboard)/admin/announcements/page.tsx第 20-32 行 - 问题:未调用
requirePermission(Permissions.ANNOUNCEMENT_MANAGE),任何登录用户可访问/admin/announcements查看所有状态公告(含草稿)和全部年级数据 - 对比:同目录
/admin/audit-logs/page.tsx第 27 行、/admin/files/page.tsx第 20 行均有权限校验 - 改进建议:增加
await requirePermission(Permissions.ANNOUNCEMENT_MANAGE) - 严重程度:P0
A-P0-2 管理端编辑页缺失权限校验
- 文件:
src/app/(dashboard)/admin/announcements/[id]/page.tsx第 16-28 行 - 问题:任何登录用户可查看任意公告完整内容(含草稿)及编辑表单
- 改进建议:同上
- 严重程度:P0
A-P0-3 公告定向推送完全失效——无受众过滤
- 文件:
src/modules/announcements/data-access.ts第 50-88 行 - 问题:
getAnnouncements仅按 status 和 type 过滤,完全不根据用户年级/班级过滤targetGradeId、targetClassId。学生 A(高一)能看到定向给"高二"的年级公告,定向推送名存实亡 - 改进建议:增加
audience?: { gradeId?, classId?, roles? }参数,查询条件增加(type='school') OR (type='grade' AND target_grade_id=:userGradeId) OR (type='class' AND target_class_id=:userClassId) - 严重程度:P0
A-P0-4 dashboard 布局无认证守卫,admin 路由无布局级权限拦截
- 文件:
src/app/(dashboard)/layout.tsx;src/app/(dashboard)/admin/无 layout.tsx - 问题:dashboard 布局仅渲染 Sidebar/Header,无认证检查。admin/ 目录无 layout.tsx 做统一 admin 角色守卫。项目根目录无 middleware.ts 做路由级拦截
- 改进建议:新增
src/app/(dashboard)/admin/layout.tsx增加await requireRole("admin"),或新增middleware.ts对/admin/*拦截 - 严重程度:P0
3.2 P1 重要问题(8 个)
| 编号 | 文件 | 问题 | 改进建议 |
|---|---|---|---|
| A-P1-1 | announcements/ 目录 | 用户端无公告详情页,用户只能看标题+3行摘要,无法查看完整正文 | 新增 /announcements/[id]/page.tsx |
| A-P1-2 | actions.ts 第 164-184 行 | 发布公告时不触发任何通知,通知基础设施已就绪但未接入 | publishAnnouncementAction 成功后调用 sendBatchNotifications |
| A-P1-3 | announcement-form.tsx | 定时发布功能完全不可用,publishedAt 无 UI 输入,无调度器 | 表单增加日期时间选择器,新增 Vercel Cron Job |
| A-P1-4 | admin/announcements/page.tsx 第 29-32 行 | 班级定向公告完全不可用,classes 数据未传递,班级下拉为空 | 并行调用 getClasses() 传入 |
| A-P1-5 | data-access.ts 第 50-88 行 | 无分页 UI,data-access 支持但页面未传入 page 参数,超过 20 条看不到 | 增加分页控件 |
| A-P1-6 | data-access.ts | 无关键词搜索 | 增加 keyword 参数和搜索框 |
| A-P1-7 | announcement-form.tsx 第 102-112 行 | 无富文本编辑,仅纯文本 Textarea | 集成 TipTap/Lexical,DOMPurify 清洗 |
| A-P1-8 | schema.ts 第 3-21 行 | 表单未校验定向目标,可创建 type=grade 但 targetGradeId=null 的无效公告 | Zod superRefine 条件校验 |
3.3 P2/P3 问题(19 个,略)
主要包括:无置顶功能、无阅读回执/已读统计、无附件/图片支持、无预览功能、无评论/反馈、不支持按角色定向、无法撤回已发布、客户端过滤与服务端过滤重复、无模板功能、无 loading.tsx、无分类标签、hidden input 冗余、formatDate 不显示时间、UI 中英文混杂、架构图与代码不一致、isWorking 状态未阻止重复提交、Dialog 关闭表单状态残留等。
3.4 同类产品对比
| 功能 | 钉钉公告 | 企业微信 | 飞书公告 | 本项目 | 差距 |
|---|---|---|---|---|---|
| 富文本编辑 | ✅ | ✅ | ✅ | 仅纯文本 | P1 |
| 附件/图片 | ✅ | ✅ | ✅ | ❌ | P2 |
| 置顶 | ✅ | ✅ | ✅ | ❌ | P2 |
| 阅读回执 | ✅ | ✅ | ✅ | ❌ | P2 |
| 定向推送 | ✅ | ✅ | ✅ | 仅年级/班级且过滤失效 | P0+P2 |
| 定时发布 | ✅ | ✅ | ✅ | 字段存在但无 UI | P1 |
| 预览 | ✅ | ✅ | ✅ | ❌ | P2 |
| 消息通知联动 | ✅ | ✅ | ✅ | ❌(基础设施已就绪) | P1 |
| 评论/反馈 | 部分 | ❌ | ✅ | ❌ | P2 |
| 撤回 | ✅ | ✅ | ✅ | 仅归档/删除 | P2 |
| 模板 | ✅ | ❌ | ✅ | ❌ | P2 |
四、Messages 消息模块(38 个问题)
4.1 P0 严重问题(3 个)
M-P0-1 缺少草稿箱
- 文件:
src/modules/messaging/data-access.ts、src/shared/db/schema.ts第 898-914 行 - 问题:
messages表无isDraft/status字段,无草稿相关 Action。用户在 MessageCompose 中输入内容后点击"取消"直接丢弃,无自动保存 - 改进建议:新增
status字段(draft/sent/trash/archived),撰写组件添加自动保存(每 30 秒)和"存为草稿"按钮 - 严重程度:P0
M-P0-2 缺少群发消息、班级消息
- 文件:
src/modules/messaging/components/message-compose.tsx第 85 行;src/modules/messaging/schema.ts第 3-9 行 - 问题:
receiverId是单个字符串,使用单选 Select,无法群发。K12 场景下教师给全班学生发消息是高频需求 - 改进建议:
receiverId改为receiverIds: string[],使用多选 Combobox,支持按班级/年级批量选择 - 严重程度:P0
M-P0-3 完全无实时推送机制
- 文件:全项目 Grep
websocket|socket.io|sse|EventSource|realtime在 messaging/notifications 模块无任何匹配 - 问题:消息和通知完全依赖页面刷新或手动 router.refresh()。教师发消息后学生看不到,除非主动刷新。与 IM 类产品实时性预期严重不符
- 改进建议:引入 SSE(Server-Sent Events)或 WebSocket,实现新消息实时推送、未读计数实时更新、在线状态指示
- 严重程度:P0
4.2 P1 重要问题(14 个)
| 编号 | 文件 | 问题 | 改进建议 |
|---|---|---|---|
| M-P1-1 | messages/page.tsx 第 22-34 行 | 消息列表与通知列表垂直堆叠,信息架构混乱 | 三栏布局或通知拆分独立 Tab |
| M-P1-2 | messages/page.tsx 第 18 行 | 无分页 UI,仅加载前 50 条,getMessagesAction 返回 totalPages 未消费 | 添加分页器或无限滚动 |
| M-P1-3 | message-detail.tsx 全文 | 无会话线程视图,getMessageThread 已实现但未使用 | 改为会话视图,底部固定回复输入框 |
| M-P1-4 | message-list.tsx 第 18 行 | 缺少星标、垃圾箱、归档,deleteMessage 是硬删除不可恢复 | 扩展表结构,改为软删除 |
| M-P1-5 | message-list.tsx 全文 | 缺少搜索、筛选、排序 | getMessages 增加 keyword/isRead/dateFrom/sortBy 参数 |
| M-P1-6 | schema.ts / message-compose.tsx | 缺少附件支持,messages 表无 attachments 字段 | 新增 message_attachments 表,集成 FileUpload |
| M-P1-7 | message-detail.tsx 第 85-100 行 | 缺少消息撤回、转发 | 新增 recallMessageAction(限时 2 分钟),转发入口 |
| M-P1-8 | navigation.ts 第 96-99 行 | 导航栏 Messages 无未读红点,getUnreadMessageCount 已实现但未调用 | 在 sidebar 渲染未读数 Badge,轮询或 SSE 推送 |
| M-P1-9 | message-compose.tsx 第 85-97 行 | 收件人选择体验差,原生 Select 无搜索无分组,all scope 一次性返回所有用户 | 改用 Combobox + 搜索,后端支持分页 |
| M-P1-10 | 全模块 | 对比同类产品缺失群聊、@提及、消息反应、置顶、模板、定时发送、已读详情、引用回复、语音消息 | 按优先级分批实现 |
| M-P1-11 | notification-dropdown.tsx 第 41-54 行 | 通知下拉仅加载一次,无实时刷新,unreadCount 只计算初始 10 条 | 添加轮询或 SSE,从专门接口获取未读总数 |
| M-P1-12 | preferences.ts 第 47-56 行 | 缺少免打扰模式和安静时段(22:00-07:00),K12 家长晚间不希望被打扰是强需求 | 新增 quietHoursStart/quietHoursEnd/vacationMode 字段 |
| M-P1-13 | data-access.ts 第 157-161 行 | 发送方删除消息会导致接收方也丢失(硬删除) | 改为软删除 + senderDeletedAt/receiverDeletedAt |
| M-P1-14 | data-access.ts | 无历史消息搜索,家长可能需要搜索上学期教师发的通知 | getMessages 增加 keyword 参数 |
4.3 P2/P3 问题(21 个,略)
主要包括:撰写页是整页跳转非抽屉、列表项缺少星标/附件/分类标识、缺少富文本、已读回执不完整、回复 subject 通过 URL 传递、通知类型映射语义错误、通知偏好无法按类别选择渠道、微信渠道形同虚设(users 表无 wechat_open_id)、通知列表与下拉内容重复、权限粒度过粗、学生互发限制未在 UI 提示、管理员删除消息权限矛盾、无归档功能、无 loading.tsx/error.tsx、客户端过滤导致数据不一致、parentMessageId 无外键约束、getMessageThread 仅一层非递归、notification-dropdown 归属 messaging 模块错误、receiverId 状态管理冗余、无键盘快捷键、notFound() 后无自定义 404 等。
4.4 同类产品对比
| 功能 | 钉钉消息 | 企业微信 | 飞书邮件 | 本项目 | 差距 |
|---|---|---|---|---|---|
| 群聊/群组 | ✅ | ✅ | ✅ | ❌ | P0 |
| 草稿箱 | ✅ | ✅ | ✅ | ❌ | P0 |
| 实时推送 | ✅ | ✅ | ✅ | ❌ | P0 |
| 消息搜索 | ✅ | ✅ | ✅ | ❌ | P1 |
| 附件支持 | ✅ | ✅ | ✅ | ❌ | P1 |
| 消息撤回 | ✅ | ✅ | ✅ | ❌ | P1 |
| @提及 | ✅ | ✅ | ✅ | ❌ | P2 |
| 消息模板 | ✅ | 部分 | ✅ | ❌ | P2 |
| 定时发送 | ✅ | ❌ | ✅ | ❌ | P2 |
| 已读详情 | ✅ | ✅ | ✅ | ❌ | P2 |
| 免打扰时段 | ✅ | ✅ | ✅ | ❌ | P1 |
五、Management 管理模块(52 个问题)
5.1 P0 严重问题(1 类,涉及 10 个页面)
MG-P0-1 多个 admin 页面缺少权限校验
- 涉及文件(10 个):
admin/school/schools/page.tsxadmin/school/academic-year/page.tsxadmin/school/classes/page.tsxadmin/school/departments/page.tsxadmin/school/grades/page.tsxadmin/school/grades/insights/page.tsxadmin/users/import/page.tsxadmin/scheduling/auto/page.tsxadmin/scheduling/changes/page.tsxadmin/scheduling/rules/page.tsx
- 问题:以上页面均未调用
requirePermission(),任何登录用户可直接访问所有 admin 管理页面,查看/操作学校、年级、班级、部门、学年、用户导入、排课等敏感数据 - 对比:
admin/audit-logs/page.tsx、admin/files/page.tsx、management/grade/classes/page.tsx均正确实现了权限校验 - 改进建议:各页面函数体首行添加对应
requirePermission()调用 - 严重程度:P0
5.2 P1 重要问题(9 个)
| 编号 | 文件 | 问题 | 改进建议 |
|---|---|---|---|
| MG-P1-1 | 全模块 | 中英文混排严重不一致,页面标题中文、组件 UI 英文、注释中文 | 统一为中文(面向 K12 中文用户) |
| MG-P1-2 | navigation.ts | 文件管理页面未在导航中注册,用户无法通过侧边栏访问 | admin 配置添加 Files 菜单项 |
| MG-P1-3 | navigation.ts 第 58 行 | 用户导入入口放在"School Management"下,且整个系统无用户管理主页面 | 创建独立 "Users" 一级菜单 |
| MG-P1-4 | 多个子路由 | 子路由缺少 loading.tsx 和 error.tsx,management/grade/ 完全不在 admin 路由树下 | 为每个子路由添加定制边界 |
| MG-P1-5 | 多个列表页 | 除审计日志外,几乎所有列表页面一次性加载全部数据,无服务端分页 | 添加 page/pageSize 参数和分页控件 |
| MG-P1-6 | 多个列表页 | 大部分列表页面缺少批量操作(批量删除/导出/编辑) | 添加复选框列和批量操作工具栏 |
| MG-P1-7 | 多个列表页 | 大部分列表页面缺少搜索和筛选 | 参考 grades-view.tsx 的实现 |
| MG-P1-8 | admin/school/page.tsx 第 6 行 | 重定向到 /admin/school/classes 跳过学校管理,层级不合理 | 改为 redirect("/admin/school/schools") |
| MG-P1-9 | admin-classes-view.tsx 第 233、247 行 | 学校和年级为自由文本输入,导致数据完整性问题 | 改为从 schools/grades 表查询的 Select |
5.3 P2/P3 问题(42 个,略)
主要包括:原生 select 而非 shadcn Select、工具函数重复、formatDate 调用不一致、admin/files 硬编码 200 条上限、排课变更缺少筛选 UI、新建申请按钮链接到 teacher 页面、schedule-change-list 无分页、scheduling-rules-form 缺少表单验证、user-import-dialog 缺少文件大小校验、预览仅显示前 50 行、不支持拖拽上传、审计日志缺少用户搜索、数据变更日志显示原始 JSON 无 diff 视图、文件管理缺少上传者信息、缺少排序功能、使用原生 a 标签、无批量审批、部门管理功能简陋、学校管理缺少搜索、学年管理缺少日期校验、admin-classes-view 与 grade-classes-view 代码重复、formatSubjectTeachers join 符号不一致、缺少面包屑导航、提交模式不一致、常量未提取、JSON.stringify 传递复杂数据、申请可提交空内容、无自动刷新、无导出功能、无重置按钮、统计仅显示前 N 项、UA 被截断、缺少空状态插图、无排序功能、缺少 dataScope 控制、缺少操作日志记录、缺少键盘快捷键、缺少数据导出、缺少数据可视化等。
5.4 同类产品对比
| 功能 | 钉钉管理后台 | 企业微信管理 | PowerSchool | 本项目 | 差距 |
|---|---|---|---|---|---|
| 权限校验 | ✅ | ✅ | ✅ | 10 页面缺失 | P0 |
| 批量操作 | ✅ | ✅ | ✅ | 仅文件管理 | P1 |
| 搜索筛选 | ✅ | ✅ | ✅ | 仅年级管理 | P1 |
| 分页 | ✅ | ✅ | ✅ | 仅审计日志 | P1 |
| 数据导出 | ✅ | ✅ | ✅ | 仅审计日志 | P3 |
| 数据可视化 | ✅ | ✅ | ✅ | 基础统计 | P3 |
| 面包屑导航 | ✅ | ✅ | ✅ | ❌ | P2 |
| dataScope | ✅ | ✅ | ✅ | ❌ | P3 |
| 键盘快捷键 | 部分 | ❌ | ❌ | ❌ | P3 |
5.5 正面发现(值得保持的良好实践)
- grades-view.tsx 是优秀范例:完整的搜索/筛选/排序、表单校验、去重校验、isDirty 检测、nuqs URL 状态管理
- admin-files-view.tsx 批量删除实现良好:复选框、全选/反选、indeterminate 状态
- file-upload.tsx 上传体验优秀:拖拽上传、进度条、文件校验、多文件并行
- 审计日志分页实现正确:分页控件和 "Showing X-Y of Z" 信息
- Promise.all 并行查询:多个页面使用 Promise.all 并行查询,性能良好
- AlertDialog 用于 destructive 操作:所有删除操作都使用 AlertDialog 确认
六、Profile 个人资料模块(部分问题)
6.1 P0 严重问题(1 个)
P-P0-1 缺少 loading.tsx 与 error.tsx
- 文件:
src/app/(dashboard)/profile/ - 问题:项目硬约束要求所有路由包含 loading.tsx 和 error.tsx,但 profile 目录只有 page.tsx
- 改进建议:新增 loading.tsx(骨架屏)和 error.tsx(错误边界+重试)
- 严重程度:P0
6.2 P1 重要问题(5 个)
| 编号 | 文件 | 问题 | 改进建议 |
|---|---|---|---|
| P-P1-1 | profile/page.tsx 行 50-118、215-300 | 页面职责混乱,混入大量仪表盘逻辑(学生学业概览+教师教学概览),303 行中 180 行是仪表盘逻辑 | 移除 Student/Teacher Overview,聚焦个人资料 |
| P-P1-2 | profile/page.tsx 行 132-213 | 缺少头像展示,users 表有 image 字段但未展示 | 在 PageHeader 下方展示头像 |
| P-P1-3 | profile-settings-form.tsx 全文 | 缺少头像上传功能,UpdateUserProfileInput 不包含 image | 增加头像上传区,扩展类型 |
| P-P1-4 | 整个 settings 模块 | 缺少隐私设置(数据可见性、第三方授权、活动记录) | 新增 Privacy Tab |
| P-P1-5 | profile/page.tsx 行 37;settings/page.tsx 行 17 | 使用 requireAuth() 而非 requirePermission(),违反项目规则 | 改为 requirePermission(USER_PROFILE_UPDATE) |
6.3 P2/P3 问题(8 个,略)
主要包括:信息展示不完整(缺监护人、教育背景、最后登录)、Edit Profile 未深链到 Tab、Age 字段应改为 Birth Date、死代码 redirect("/login")、PageHeader 未复用等。
七、Settings 设置模块(部分问题)
7.1 P0 严重问题(1 个)
S-P0-1 缺少 loading.tsx 与 error.tsx
- 文件:
src/app/(dashboard)/settings/、src/app/(dashboard)/settings/security/ - 问题:同 profile,违反项目硬约束
- 改进建议:两个目录均新增 loading.tsx 和 error.tsx
- 严重程度:P0
7.2 P1 重要问题(9 个)
| 编号 | 文件 | 问题 | 改进建议 |
|---|---|---|---|
| S-P1-1 | settings/page.tsx 行 27-33 | 角色路由缺失 parent 分支,parent 用户被错误渲染为 TeacherSettingsView | 显式处理 parent 角色 |
| S-P1-2 | settings-view.tsx 行 63-81 | Tab 分类不齐全,缺少 AI Providers、Privacy、Account、Language & Region | 扩展为 6 个 Tab |
| S-P1-3 | settings/security/page.tsx 全文 | 缺少两步验证(2FA)、登录设备管理、登录历史 | 新增 2FA 设置区、设备管理卡片、登录历史卡片 |
| S-P1-4 | settings-view.tsx 行 83-86 | AiProviderSettingsCard 已存在但未在 SettingsView 中使用 | 在 General 或新增 AI Tab 中渲染 |
| S-P1-5 | notification-preferences-form.tsx 全文 | 缺少免打扰时段(DND)设置 | 新增 DND 卡片 |
| S-P1-6 | settings-view.tsx 行 63 | Tab 切换无 URL 持久化,刷新回到 General,无法分享特定 Tab 链接 | useSearchParams 实现 URL 同步 |
| S-P1-7 | password-change-form.tsx 行 22-24 | 使用任意值 Tailwind 类 [&>div]:bg-red-500,违反项目规则 |
在 globals.css 定义工具类 |
| S-P1-8 | 整个 settings 模块 | 无快捷键自定义功能 | 新增 Keyboard Shortcuts 设置区 |
| S-P1-9 | settings-view.tsx 行 63-81 | Tabs 缺少键盘箭头导航验证 | 确认 Radix Tabs ARIA 实现 |
7.3 P2/P3 问题(17 个,略)
主要包括:Appearance Tab 内容单薄(无字体大小/密度/语言/时区)、settings/security 与 SettingsView Security Tab 内容重复、邮箱不可修改、Age 应改为 BirthDate、密码修改后未登出其他会话、缺少密码历史检查、缺少邮件摘要频率、缺少按类别渠道覆盖、缺少删除 AI Provider、AI Provider 强制测试才能保存、Tab 切换无未保存变更警告、通知偏好无即时反馈、登出无二次确认、错误信息泄露用户存在性、AI Provider 测试无频率限制、ProfileSettingsForm 无错误状态展示、AiProviderSettingsCard 加载失败无重试、bcrypt salt rounds 偏低、主题描述硬编码 "admin console"、ProfileSettingsForm 无 Cancel/Reset、中文错误信息、中文注释等。
7.4 同类产品对比
| 功能 | Google 账户 | GitHub Settings | 钉钉设置 | 本项目 | 差距 |
|---|---|---|---|---|---|
| 头像上传 | ✅ | ✅ | ✅ | ❌ | P1 |
| 2FA | ✅ | ✅ | ✅ | ❌ | P1 |
| 登录设备管理 | ✅ | ✅ | ✅ | ❌ | P1 |
| 登录历史 | ✅ | ✅ | ✅ | ❌ | P1 |
| 通知免打扰 | ✅ | ✅ | ✅ | ❌ | P1 |
| 语言切换 | ✅ | ✅ | ✅ | ❌ | P2 |
| 时区设置 | ✅ | ✅ | ✅ | ❌ | P2 |
| 第三方授权管理 | ✅ | ✅ | ✅ | ❌ | P1 |
| 数据导出 | ✅ | ✅ | ✅ | ❌ | P2 |
| 删除账户 | ✅ | ✅ | ✅ | ❌ | P2 |
| Tab URL 持久化 | ✅ | ✅ | ✅ | ❌ | P1 |
| 未保存变更警告 | ✅ | ✅ | ✅ | ❌ | P2 |
八、跨模块共性问题
8.1 安全问题集中爆发
12 个 P0 权限校验缺失:
- announcements 模块 2 个(admin 列表页+编辑页)
- management 模块 10 个(admin/school/* 6 个 + admin/users/import 1 个 + admin/scheduling/* 3 个)
- dashboard 布局无认证守卫
根因分析:项目缺少统一的 admin 路由守卫机制。建议在 src/app/(dashboard)/admin/layout.tsx 增加统一 requireRole("admin") 或 requirePermission() 检查,或新增 middleware.ts 对 /admin/* 路径拦截。
8.2 中英文混排严重
| 模块 | 页面标题 | 组件 UI | 注释 |
|---|---|---|---|
| Dashboard | 英文 | 英文 | 英文 |
| Announcements | 中文(metadata) | 英文 | 英文 |
| Messages | 英文 | 英文 | 英文 |
| Management | 中文(大部分) | 中英混排 | 中文 |
| Profile | 英文 | 英文 | 英文 |
| Settings | 英文 | 英文 | 中英混排 |
改进建议:建立统一 i18n 策略,推荐统一为中文(面向 K12 中文用户),或接入 next-intl。
8.3 loading.tsx / error.tsx 大面积缺失
| 模块 | 缺失目录 |
|---|---|
| Dashboard | teacher/dashboard、parent/dashboard、dashboard |
| Announcements | announcements、admin/announcements |
| Messages | messages、messages/[id]、messages/compose |
| Management | admin/school/、admin/scheduling/、admin/users/import、management/grade/* |
| Profile | profile |
| Settings | settings、settings/security |
改进建议:为所有缺失目录添加 loading.tsx(骨架屏)和 error.tsx(错误边界+重试按钮)。
8.4 列表页分页/搜索/批量操作三件套缺失
| 模块 | 分页 | 搜索 | 批量操作 |
|---|---|---|---|
| Announcements | ❌ | ❌ | N/A |
| Messages | ❌ | ❌ | N/A |
| Management(school/*) | ❌ | 仅 grades-view | ❌ |
| Management(audit-logs) | ✅ | ❌ | ✅(导出) |
| Management(files) | ❌ | ✅ | ✅(删除) |
改进建议:以 grades-view.tsx(搜索/筛选/排序)和 admin-files-view.tsx(批量操作)为范例,统一补齐。
8.5 实时性全面缺失
全项目无 WebSocket/SSE 实现,消息、通知、仪表盘数据均依赖页面刷新。对比钉钉/企业微信/飞书等 IM 类产品,实时性是核心差距。
改进建议:引入 SSE(Server-Sent Events),Next.js 14+ 支持 Route Handler 实现 SSE,成本低于 WebSocket。优先实现消息实时推送和通知实时刷新。
九、优先级修复建议
9.1 立即修复(P0,14 个)
- 权限校验(12 个页面):为所有缺失
requirePermission()的 admin 页面添加权限校验 - admin 布局守卫:新增
src/app/(dashboard)/admin/layout.tsx统一守卫 - 公告定向推送:修复
getAnnouncements增加受众过滤 - 消息草稿箱:扩展 messages 表 status 字段
- 消息群发:支持多收件人
- 实时推送:引入 SSE
- StudentStatsGrid:补全 props 渲染
- loading/error 边界:为 teacher/parent/dashboard 添加
- TeacherDashboardHeader 问候语:修复硬编码
9.2 短期修复(P1,52 个)
- Dashboard:AdminDashboard 快捷操作、Parent 多子女对比、角色切换器、col-span 修复
- Announcements:用户端详情页、通知联动、定时发布、班级数据传递、分页、搜索、富文本、表单校验
- Messages:会话线程、软删除、搜索筛选、附件、撤回转发、未读红点、收件人 Combobox、免打扰时段、通知实时刷新
- Management:中英文统一、文件管理导航、用户管理主页面、loading/error 边界、分页、批量操作、搜索筛选、学校年级 Select
- Profile/Settings:职责拆分、头像展示上传、parent 角色路由、Tab 分类扩展、2FA/设备管理/登录历史、AiProvider 集成、DND、URL 持久化、权限校验
9.3 中期修复(P2,81 个)
富文本编辑、附件支持、置顶、阅读回执、预览、评论、按角色定向、撤回、模板、归档、@提及、消息反应、定时发送、已读详情、引用回复、通知类型映射重构、组件归属迁移、批量审批、表单校验、代码重复提取、面包屑导航等。
9.4 长期优化(P3,54 个)
数据可视化、dataScope 控制、键盘快捷键、数据导出、空状态插图、focus-visible 样式、返回顶部、移动端适配、i18n、架构图同步等。
十、架构图同步提醒
根据项目规则"改码必同步图",以下修复完成后需要同步更新架构文档(004_architecture_impact_map.md 和 005_architecture_data.json):
- 新增
admin/layout.tsx→ 更新 app 路由结构 - 新增
announcements/[id]/page.tsx→ 更新 announcements 路由 - messages 表新增 status/isStarred/isArchived 字段 → 更新 dbTables
- 新增
ParentSettingsView→ 更新 settings 模块 exports AiProviderSettingsCard集成到 SettingsView → 更新组件依赖- 新增
deleteAiProviderAction→ 更新 settings 模块 actions - 新增 privacy/2FA 相关 action → 更新 settings 模块职责
notification-dropdown.tsx迁移到 notifications 模块 → 更新模块归属insertAnnouncement返回类型Promise<{ announcementId: string }>→ 实际为Promise<string>,需修正文档- 抽取
getPrimaryRole工具函数 → 更新 shared/lib exports
附录:审查文件清单
Dashboard 模块
src/app/(dashboard)/dashboard/page.tsxsrc/app/(dashboard)/admin/dashboard/page.tsxsrc/app/(dashboard)/teacher/dashboard/page.tsxsrc/app/(dashboard)/student/dashboard/page.tsxsrc/app/(dashboard)/parent/dashboard/page.tsxsrc/modules/dashboard/components/下所有组件src/modules/layout/components/app-sidebar.tsxsrc/modules/layout/components/site-header.tsxsrc/modules/layout/config/navigation.ts
Announcements 模块
src/app/(dashboard)/announcements/page.tsxsrc/app/(dashboard)/admin/announcements/page.tsxsrc/app/(dashboard)/admin/announcements/[id]/page.tsxsrc/modules/announcements/下所有文件
Messages 模块
src/app/(dashboard)/messages/page.tsxsrc/app/(dashboard)/messages/[id]/page.tsxsrc/app/(dashboard)/messages/compose/page.tsxsrc/modules/messaging/下所有文件src/modules/notifications/下所有文件
Management 模块
src/app/(dashboard)/management/grade/下所有页面src/app/(dashboard)/admin/school/下所有页面src/app/(dashboard)/admin/users/import/page.tsxsrc/app/(dashboard)/admin/audit-logs/下所有页面src/app/(dashboard)/admin/files/page.tsxsrc/app/(dashboard)/admin/scheduling/下所有页面src/modules/classes/components/下相关组件src/modules/school/components/下所有组件src/modules/audit/components/下所有组件src/modules/files/components/下所有组件src/modules/scheduling/components/下所有组件src/modules/users/components/下所有组件
Profile & Settings 模块
src/app/(dashboard)/profile/page.tsxsrc/app/(dashboard)/settings/page.tsxsrc/app/(dashboard)/settings/security/page.tsxsrc/modules/settings/components/下所有组件src/modules/settings/下所有文件src/modules/users/data-access.tssrc/modules/users/user-service.ts
本报告由 5 个子代理并行深度审查整合生成,覆盖 6 大模块、50+ 页面、100+ 组件,共发现 201 个问题。建议按 P0 → P1 → P2 → P3 优先级分四个迭代周期完成核心功能补齐,每个迭代同步更新架构图 004/005 文档。