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)
182 lines
8.9 KiB
Markdown
182 lines
8.9 KiB
Markdown
# 前端规范审查报告 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` | 修复不存在的权限常量 |
|
||
|
||
---
|
||
|
||
## 六、剩余建议(非阻塞,可在后续迭代处理)
|
||
|
||
1. **teacher 页面 JSX 命名空间错误**:React 19 移除了全局 `JSX` 命名空间,需将 `JSX.Element` 改为 `React.ReactElement` 或导入 `React`。建议批量修复。
|
||
2. **settings-view 组件复用**:`admin/teacher/student-settings-view.tsx` 三个文件结构高度相似,可提取共享 `SettingsLayout` 组件减少重复代码。
|
||
3. **预存 warning 清理**:7 个 `no-unused-vars` warning 可在后续清理。
|
||
4. **classes/actions.ts、exams/actions.ts 类型修复**:预存类型不兼容问题需单独处理。
|