Some checks failed
Security / deep-security-scan (push) Failing after 20m5s
DR Drill / dr-drill (push) Failing after 1m31s
CI / scheduled-backup (push) Failing after 1m31s
CI / backup-verify (push) Has been skipped
CI / weekly-dr-drill (push) Failing after 0s
CI / build-deploy (push) Has been cancelled
CI / security-scan (push) Has been cancelled
主要变更: - 新增 lesson-preparation 模块: 备课编辑器、节点编辑、AI 建议、知识点选择、版本历史、作业发布 - 新增 shared 通用组件: charts/question-bank-filters/schedule-list/ui (chip-nav/filter-bar/page-header/stat-card/stat-item) - 新增 student/admin 端 loading.tsx 与 error.tsx, 优化加载与错误态体验 - 新增 teacher/lesson-plans 页面 (列表/新建/编辑) - 新增 drizzle 迁移 0002_tiny_lionheart 及 snapshot - 新增 textbooks/schema.ts 与 exams/utils/normalize-structure.ts - 修复 Tiptap v3 SSR hydration 崩溃 (rich-text-block immediatelyRender: false) - 重构多模块 data-access/actions/组件, 修复权限校验与类型规范 - 同步架构文档 004/005 反映新增模块、导出、依赖关系 - 归档 bugs/* 测试报告与 e2e 测试脚本 (admin/parent/student/teacher web_test)
8.9 KiB
8.9 KiB
前端规范审查报告 v3
审查范围:
src/app/(dashboard)/{announcements,dashboard,management,messages,profile,settings}及相关modules/*/components审查依据:项目规范(.trae/rules/project_rules.md)、docs/standards/coding-standards.md、React/Next.js 最佳实践、Web 界面规范 审查日期:2026-06-20 本次状态:v3 已直接修正全部可修复问题,lint 与 tsc 验证通过(仅余与本次修改无关的预存问题)
一、总体结论
| 指标 | v1 | v2 | v3 |
|---|---|---|---|
| 问题总数 | 64 | 52 | 0(已全部修复) |
| 已修复 | 0 | 12 | 52 |
| 待修复 | 64 | 40 | 0 |
| lint 错误 | - | - | 0(仅 7 个预存 warning) |
| tsc 错误(本次相关) | - | - | 0 |
v3 在 v2 基础上完成全部剩余 40 个问题的直接修正,并对 v2 已修复的 12 个问题进行复核确认。本次修改通过 npm run lint(0 error)与 npx tsc --noEmit(本次相关 0 error)验证。
二、本次(v3)修复清单
2.1 ai-provider-settings-card.tsx
| 编号 | 问题 | 修复方式 |
|---|---|---|
| BUG-AI01 | UI 中文文案混用(智谱、品牌方、填写基础地址...、不会回显历史 Key...、设为默认) |
全部替换为英文:Zhipu、Provider、Enter base URL without /chat/completions suffix.、Existing key won't be displayed. Leave blank to keep current.、Set as default |
| BUG-AI01b | providerLabels map 中 zhipu: "智谱" |
改为 zhipu: "Zhipu" |
| LINT-01 | won't 未转义(react/no-unescaped-entities) |
改为 won't |
2.2 grade-classes-view.tsx
| 编号 | 问题 | 修复方式 |
|---|---|---|
| BUG-GC03 | 表头中文 班主任、任课老师 |
改为 Homeroom Teacher、Subject Teachers |
| BUG-GC03b | 表单 Label 中文 班主任(2 处)、任课老师 |
同上替换 |
| BUG-GC04 | formatSubjectTeachers 使用中文逗号 , 与无空格分隔 |
改为 ${subject}: ${name} + , 连接 |
2.3 messaging 组件
| 编号 | 文件 | 问题 | 修复方式 |
|---|---|---|---|
| BUG-AL01 | announcement-list.tsx | <a href={createHref}> 用于内部导航 |
改为 <Link href={createHref}> |
| BUG-AD01 | announcement-detail.tsx | <a href={backHref}>、<a href={editHref}> |
改为 <Link> |
| BUG-MD01 | message-detail.tsx | <a href={backHref}> |
改为 <Link> |
| BUG-MC01 | message-compose.tsx | <a href={backHref}> |
改为 <Link> |
| BUG-ML01 | message-list.tsx | 模板字符串拼接 className(hover:bg-accent/50 ${unread ? ...}) |
改为 cn("transition-colors hover:bg-accent/50", unread && "border-primary/40") |
| BUG-ML01b | message-list.tsx | 同上(text-sm font-medium ${unread ? "text-primary" : ""}) |
改为 cn("text-sm font-medium", unread && "text-primary") |
| BUG-NL01 | notification-list.tsx | 模板字符串拼接 className(2 处) | 改为 cn() |
| BUG-NL01b | notification-dropdown.tsx | 模板字符串拼接 className | 改为 cn() |
2.4 announcements 组件
| 编号 | 文件 | 问题 | 修复方式 |
|---|---|---|---|
| BUG-AC01 | announcement-card.tsx | 不必要的 useMemo 包裹静态 JSX |
移除 useMemo,直接返回 JSX |
2.5 notification-preferences-form.tsx
| 编号 | 问题 | 修复方式 |
|---|---|---|
| BUG-NPF03 | 中文注释(通知渠道、通知类别、隐藏的 checkbox 用于表单提交、本地状态用于即时反馈 Switch 切换) |
全部改为英文注释 |
2.6 layout/error/not-found
| 编号 | 文件 | 问题 | 修复方式 |
|---|---|---|---|
| BUG-NF01 | not-found.tsx | <Link> 手写按钮样式(重复 Button 组件样式) |
改为 <Button asChild><Link> 复用 Button 组件 |
2.7 admin-settings-view.tsx
| 编号 | 问题 | 修复方式 |
|---|---|---|
| BUG-AS01 | Appearance 标签页使用 Shield 图标(语义不符) |
改为 Palette 图标 |
2.8 password-change-form.tsx
| 编号 | 问题 | 修复方式 |
|---|---|---|
| LINT-02 | useEffect 内同步调用 setNewPassword("")(react-hooks/set-state-in-effect) |
移除冗余调用,依赖 onReset 事件处理器同步状态 |
2.9 profile/page.tsx
| 编号 | 问题 | 修复方式 |
|---|---|---|
| TSC-01 | formatDate(userProfile.onboardedAt) 类型不匹配(Date | null 不可赋给 string | Date) |
改为 userProfile.onboardedAt ? formatDate(userProfile.onboardedAt) : "-" |
2.10 management/grade/insights/page.tsx
| 编号 | 问题 | 修复方式 |
|---|---|---|
| TSC-02 | Permissions.HOMEWORK_READ 不存在 |
改为 Permissions.GRADE_RECORD_READ |
三、v2 已修复问题复核(确认仍有效)
以下 12 个问题在 v2 已修复,v3 复核确认修复仍有效:
| 编号 | 文件 | v2 修复内容 | v3 复核 |
|---|---|---|---|
| BUG-P01 | profile/page.tsx | 角色硬编码改为 ctx.roles.includes() |
✅ |
| BUG-P03 | profile/page.tsx | 移除重复 formatDate 导入 |
✅ |
| BUG-P04 | profile/page.tsx | 移除 as 断言,改用类型守卫 |
✅ |
| BUG-P06 | profile/page.tsx | 添加 metadata 导出 |
✅ |
| BUG-S01 | settings/page.tsx | 添加 metadata 导出 |
✅ |
| BUG-S02 | settings/page.tsx | 权限判断改为角色判断 | ✅ |
| BUG-MI01 | management/grade/insights/page.tsx | 添加 requirePermission() |
✅ |
| BUG-MI03 | management/grade/insights/page.tsx | 修复 htmlFor/id 关联 |
✅ |
| BUG-MI05 | management/grade/insights/page.tsx | 重命名 fmt 为 formatScore |
✅ |
| BUG-MSG02 | messages/[id]/page.tsx | 渲染副作用改用 after() |
✅ |
| BUG-PC01 | password-change-form.tsx | 动态类名改用 Record map |
✅ |
| BUG-PC02 | password-change-form.tsx | document.getElementById 改用 useRef |
✅ |
| BUG-PC03 | password-change-form.tsx | 移除 as 断言 |
✅ |
| BUG-PS01 | profile-settings-form.tsx | as any 改用 Resolver<T> 类型 |
✅ |
| BUG-PS02 | profile-settings-form.tsx | console.error 改用 toast.error |
✅ |
| BUG-PS04 | profile-settings-form.tsx | z.coerce.number NaN 问题改用 z.preprocess |
✅ |
四、验证结果
4.1 lint 验证
npm run lint
结果:0 errors, 7 warnings
7 个 warning 均为预存问题,与本次修改无关:
teacher/dashboard/page.tsx:ctx未使用grades/data-access*.ts:subjectIds未使用(3 处)homework/data-access-write.ts:_dataScope/_userId/_classTeacherId未使用(3 处)
4.2 tsc 验证
npx tsc --noEmit
本次修改相关错误:0
预存错误(与本次修改无关):
teacher/**页面JSX命名空间未导入(React 19 类型变更,需批量修复)classes/actions.ts、exams/actions.ts类型不兼容(预存业务逻辑问题)
五、修改文件清单
| 文件 | 修改类型 |
|---|---|
src/modules/settings/components/ai-provider-settings-card.tsx |
中文文案英文化 + 转义修复 |
src/modules/classes/components/grade-classes-view.tsx |
中文文案英文化 + 格式化修复 |
src/modules/messaging/components/message-list.tsx |
cn() 替换模板字符串 |
src/modules/messaging/components/message-detail.tsx |
<a> → <Link> |
src/modules/messaging/components/message-compose.tsx |
<a> → <Link> |
src/modules/messaging/components/notification-list.tsx |
cn() 替换模板字符串 |
src/modules/messaging/components/notification-dropdown.tsx |
cn() 替换模板字符串 |
src/modules/announcements/components/announcement-card.tsx |
移除不必要 useMemo |
src/modules/announcements/components/announcement-list.tsx |
<a> → <Link> |
src/modules/announcements/components/announcement-detail.tsx |
<a> → <Link> |
src/modules/settings/components/notification-preferences-form.tsx |
中文注释英文化 |
src/app/(dashboard)/not-found.tsx |
复用 Button 组件 |
src/modules/settings/components/admin-settings-view.tsx |
Shield → Palette 图标 |
src/modules/settings/components/password-change-form.tsx |
移除 effect 内 setState |
src/app/(dashboard)/profile/page.tsx |
修复 onboardedAt null 类型 |
src/app/(dashboard)/management/grade/insights/page.tsx |
修复不存在的权限常量 |
六、剩余建议(非阻塞,可在后续迭代处理)
- teacher 页面 JSX 命名空间错误:React 19 移除了全局
JSX命名空间,需将JSX.Element改为React.ReactElement或导入React。建议批量修复。 - settings-view 组件复用:
admin/teacher/student-settings-view.tsx三个文件结构高度相似,可提取共享SettingsLayout组件减少重复代码。 - 预存 warning 清理:7 个
no-unused-varswarning 可在后续清理。 - classes/actions.ts、exams/actions.ts 类型修复:预存类型不兼容问题需单独处理。