2026-06-01-FE-02.md 5.82 KB

FE-02 主页与导航框架 — 代码审阅报告(第 1 轮)

  • 规格:docs/superpowers/specs/2026-06-01-FE-02.md
  • 阶段:前端(frontend)
  • 裁决:approve
  • 轮次:1
  • 审阅范围:自 FE-01 approve(3119517)至 HEADfrontend/ 增量 diff(39 文件,2579+ 行)

一、结论

FE-02 应用外壳(TopBar + NavOverlay + 标签栈 + 路由壳 + 路由守卫)与主页 KPI 看板落地页实现质量良好,与规格 / 原型 / Design Tokens 一致,未发现客观可验证的 must-fix 缺陷。验证基线:

  • npm run lint:通过(无 error / warning)。
  • npx tsc --noEmit:通过(exit 0)。
  • npm run test:unit:25 文件 / 88 用例全绿。
  • e2e tests/e2e/shell.spec.ts:覆盖登录落地 / 导航浮层开关+Esc / 标签开关联动 / 退出登录 / 未登录重定向 5 条关键旅程。
  • 作用域:全部改动落在 frontend/(与 docs/),未触碰 backend/ / sql/ / scripts/,符合前端阶段硬作用域。

二、前端 7 维 checklist 逐项

1. 原型一致性(客观)— 通过

  • TopBar 复刻 #topbar:Logo(鹿角 SVG,点击回主页)+ 「全部导航」按钮 + 标签条(主页固定 + 业务标签可关)+ 右侧 搜索/通知/当前用户/更多,位置与原型 .right 一致。
  • NavOverlay 复刻 #nav-overlay:左列 20 项一级模块(navConfig.NAV_SIDE,「系统设置」default active),右侧 7 列分组(NAV_COLS,标题与叶子标签逐字对齐 navCols,「用户列表」「系统功能模块设置」带 ★)。
  • HomePage 复刻 #screen-main1fr / 280px 主网格、kpi-head(标题 + 今日未处理/未清总数 + AI 按钮)、three-col(左角色/流程树 + 右 KPI 合并网格)、common-ops(「用户列表」路由 + 「系统功能模块设置」占位,与原型两条链接对齐)、footer.foot 文案逐字复刻。
  • KPI 合并网格用 CSS Grid gridRow span 复刻(D5 兜底路径),KPI_ROWS 17 行 + roleSpan/subSpan/red 与原型 kpiRows 逐字一致。
  • 结论:主操作位置、栅格列数、关键区域布局均无结构性偏移。

2. Design Tokens(客观)— 通过

  • 语义色(主操作/文字/边框/错误/成功/表头/行 hover/选中)全部走 var(--color-*),与 src/styles/tokens.css 对齐。
  • 仅顶栏 #1f1f23 / overlay #2b3137 等品牌深色 chrome 硬编码于 AppLayout.module.css scoped 样式——由 D9 显式登记(tokens.css 无对应品牌深色语义 token,且为纯装饰非状态语义),与 FE-01 § 7 D7 处理一致,不违反「语义色只用 token」约束。
  • 未发现未登记的新 token。

3. 无障碍(best-effort,仅客观项可 must-fix)— 通过

  • 交互控件可达:Logo aria-label;「全部导航」aria-pressed;标签关闭「✕」role=button/tabIndex=0/aria-label/Enter+Space 键盘触发;NavOverlay role=dialog/aria-modal;角色树项 aria-pressed
  • 退出登录走 AntD Dropdown 菜单项(键盘可达)。
  • 搜索/通知/更多图标为 aria-hidden 纯装饰占位(D4,无业务交互),不构成可达性缺陷。
  • 注:本壳层无破坏性操作(删除/不可逆),故确认对话框不适用。

4. 响应式(best-effort)— 不阻断

  • 桌面定宽 ERP(D8),不设移动断点。符合规格,且按规约响应式不单独触发 request-changes。

5. 业务规则前端复刻(客观)— 通过

  • BR1 未登录守卫(RequireAuth<Navigate to="/login" state.from>);BR2 已登录访问 /login 回跳(RedirectIfAuthed);BR3 当前用户 sUserName(sUserType) + 缺失退化占位;BR4/5/6 标签栈固定主页/联动关闭/隐式开父标签(useTabStack);BR7 占位项「功能开发中」;BR8 用户列表跳转 /usr/users;BR9 退出登录清态+跳登录+message.success;BR10 被动 401 统一登出(registerUnauthorizedHandler + 拦截器);BR11 KPI/树只读高亮无副作用。均落地。

6. API 调用一致性(客观)— 通过

  • 壳层不直接调用业务端点(与 docs/05 一致,无 KPI/dashboard/nav 端点,D1 不杜撰)。
  • request.ts 为 FE-01 已建统一 Axios 实例(baseURL=/api);FE-02 仅新增 401 统一登出回调单例 + 拦截器分支,无 raw fetch / 手拼 URL。

7. 状态机覆盖(客观)— 通过

  • authResolvingSpin 占位)/ unauthenticatedNavigate)/ ready(外壳就绪)/ navOverlayOpen / tabOpen / empty(KPI Empty 兜底)/ errorAppErrorBoundary Result + 返回主页)均处理。
  • 「提交中」对本壳层不适用(无提交动作),规格 § 3 已将 5 态映射到外壳语义,非缺失。

三、通用维度

  • 计划对齐:组件树 / 路由表 / decisions(D1~D10)与规格一一对应。
  • 质量:lint/tsc/unit/e2e 全绿;文案集中于 shellMessages.ts 单一来源;标签栈逻辑抽为可测 hook。
  • 架构:壳层 UI 态用本地 useState(D3),登录态复用 Redux authSlice,关注点分离清晰;401 回调单例解了「拦截器内无 React hooks」问题。
  • 文档/注释:每文件含 REQ-USR-003/004 追溯注释,符合 CLAUDE.md 约定。

四、建议(非 must-fix,不计入 issues)

  • AppErrorBoundary.handleGoHomewindow.location.assign('/') 触发整页刷新而非 SPA 路由跳转,存在轻微 UX 损耗(会丢失 SPA 状态)。功能正确,且注释已说明 class 组件无 hooks 约束;如后续优化可注入 navigate 或改 useNavigate 包装。属可选改进,不阻断。
  • KpiBoard props 保留未使用的 onNavigate(KPI 链接纯展示);可在后续清理,无功能影响(lint 已通过,未触发 unused 规则因其为可选 prop)。

五、issues(must-fix)

无。verdict = approveissues = []