Commit da220641c43aea3de1203c9d9e5817db3e18fd8c
1 parent
49e50b48
docs(review:FE-01:r1): approve
Showing
1 changed file
with
53 additions
and
0 deletions
docs/superpowers/reviews/2026-06-01-FE-01.md
0 → 100644
| 1 | +# FE-01 登录页 — AI 自审报告(第 1 轮) | ||
| 2 | + | ||
| 3 | +- 阶段:前端(frontend) | ||
| 4 | +- 关联 REQ:REQ-USR-004(主);配套 `GET /api/usr/companies` | ||
| 5 | +- 关联原型:`prototype/erp.html` → `<section id="screen-login">` | ||
| 6 | +- 规格:`docs/superpowers/specs/2026-06-01-FE-01.md` | ||
| 7 | +- 裁决:**approve** | ||
| 8 | +- must-fix issues:无(空数组) | ||
| 9 | + | ||
| 10 | +## 审阅范围 | ||
| 11 | + | ||
| 12 | +本轮 diff(自 `2dce637^` 起的 FE-01 提交链)落在 `frontend/` 内,作用域合规,未触碰 `backend/` / `sql/` / `scripts/`。核心文件: | ||
| 13 | + | ||
| 14 | +- `frontend/src/pages/usr/Login/LoginPage.tsx` | ||
| 15 | +- `frontend/src/pages/usr/Login/Login.module.css` | ||
| 16 | +- `frontend/src/pages/usr/Login/loginMessages.ts` | ||
| 17 | +- `frontend/src/api/{request.ts,types.ts,usrApi.ts}` | ||
| 18 | +- `frontend/src/store/slices/authSlice.ts`、`frontend/src/router/index.tsx`、`frontend/src/App.tsx`、`frontend/src/styles/theme.ts` | ||
| 19 | + | ||
| 20 | +## 质量闸(独立复跑验证) | ||
| 21 | + | ||
| 22 | +- `tsc --noEmit`:通过(exit 0)。 | ||
| 23 | +- `vitest run`:10 文件 / 32 用例全绿(含布局、版本预加载/空态/重试、校验、提交中态、错误码分流、成功落地、authSlice、request 拦截器)。 | ||
| 24 | +- `eslint .`:通过(exit 0)。 | ||
| 25 | + | ||
| 26 | +## 前端 7 维 checklist | ||
| 27 | + | ||
| 28 | +1. **原型一致性(客观)— 通过**:复刻 `.login-wrap` 三段式(品牌头 / 深蓝主视觉+右侧浮层登录卡 / 页脚版权);登录卡 `right:8% top:50% translateY(-50%)`、宽 380px、主操作为底部 `block` 主按钮,与原型 DOM 结构与主操作位置一致。下拉以 AntD `Select` 等价复刻原型 `.lf.dropdown`,属允许的实现差异。 | ||
| 29 | +2. **Design Tokens(客观)— 通过**:语义色(按钮 / 文字 / 标题 / 占位 / 边框 / 背景 / 错误)全部走 `var(--color-*)`,无硬编码。`Login.module.css` 中的 hex/rgba 全部位于 `.hero` 主视觉装饰(深蓝渐变 / 网格透视 / hero 文案)及阴影 alpha,属规格 D7 明确豁免的「登录页局部装饰,不挪用语义 token、不新增全局 token」。`LoginPage.tsx` 内两处 `fill="#0e1216"` / `#3a6cb6` 为原型逐字复刻的品牌 Logo / ICP 图标 SVG 装饰填充,非语义 UI 色,归同一装饰豁免。`theme.ts` 的 `#1890ff` 为读取 `--color-primary` 失败时的兜底常量(= token 现值),运行时优先读 CSS 变量。token 优先于原型的色值精度差异处理正确(原型品牌名为琥珀色 `#e0a020`,实现改用 `--color-primary`,符合「tokens.css 优先于 prototype」)。 | ||
| 30 | +3. **无障碍(best-effort)**:表单控件仅用 `placeholder`,无显式 `<label>`/`aria-label`——但原型本身即 placeholder-only 无 label 区,规格未要求可见标签,故按 best-effort 处理,不作 must-fix(建议项见下)。装饰 SVG 正确带 `aria-hidden`;无危险/不可逆操作,无需确认弹窗;支持回车提交(AntD Form 默认),键盘可达。 | ||
| 31 | +4. **响应式(best-effort)**:`@media (max-width:768px)` 将卡片回流为居中静态布局(D4)。目标用户为桌面端 ERP,无 must-fix。 | ||
| 32 | +5. **业务校验前端复刻(客观)— 通过**:BR1/BR2/BR4 用 AntD `Form` 必填校验(文案「请输入用户名」「请输入密码」「请选择版本」);BR3 `Input.Password` 掩码;BR6/BR7/BR8 错误码 40101/40302/42901 文案与后端语义一致且不细化枚举;BR9 成功落地;BR10 `submitting` 期间禁用+早返回防重复提交;BR11 明文原样提交。 | ||
| 33 | +6. **API 调用一致性(客观)— 通过**:`POST /api/usr/login`、`GET /api/usr/companies` 均经统一 `request.ts` Axios 实例,无裸 `fetch`/手拼 URL。请求体 `{sUserName,password,companyId}`、响应 `{token,user:{id,sUserName,sUserType,sLanguage}}`、公司项 `{id,sCompanyName,sVersion}` 与 docs/05 + REQ-USR-004 后端规格(§2.3 / §8 D1,含 `GET /api/usr/companies` 与 `42901` 限流码)一致。响应拦截器拆 `Result`、登录端点不强制带 token,符合 docs/04 § 2.3/2.4。 | ||
| 34 | +7. **状态机覆盖(客观)— 通过**:5 态齐备——`companiesLoading`(Select `loading`+禁用+占位「加载版本中…」)、`idle`、`empty`(`notFoundContent="暂无可用版本"`+轻提示)、`submitting`(按钮 loading + Form 整体 `disabled` + 早返回)、`error`(错误码分流 `message.error` + 版本失败重试入口)、`success`(`setCredentials` + 持久化 + `navigate('/',{replace:true})`)。 | ||
| 35 | + | ||
| 36 | +## 通用四维 | ||
| 37 | + | ||
| 38 | +- 计划对齐:实现与 spec §2-§7 / REQ-USR-004 输入表逐项对应,自主决策 D1-D8 在代码注释与结构中可追溯。 | ||
| 39 | +- 质量:错误处理集中在响应拦截器 + 页面错误码映射;TS 类型契约(`types.ts`)跨 task 共享;测试覆盖充分;登录端点放行、token 仅登录态注入,无明显安全/性能问题。 | ||
| 40 | +- 架构:api / store / pages / router / styles 分层清晰,页面只调 `usrApi`,不散用 axios;token 持久化键 `TOKEN_STORAGE_KEY` 单点定义。 | ||
| 41 | +- 文档:文件含 `REQ-USR-004` 注释与决策追溯,符合 CLAUDE.md 约定。 | ||
| 42 | + | ||
| 43 | +## 非阻塞建议(口头,不入 issues) | ||
| 44 | + | ||
| 45 | +- A11y 增强(建议):可为用户名 / 密码 / 版本三控件补 `aria-label`(如「用户名」「密码」「版本」),在 placeholder-only 布局下提升读屏可用性。非 must-fix。 | ||
| 46 | +- `authSlice.setCredentials` reducer 内做 `localStorage` 写副作用为 MVP 取舍(D6 已登记),后续如引入 SSR/严格纯 reducer 规范可迁至中间件或 thunk。非本轮阻塞。 | ||
| 47 | + | ||
| 48 | +## 决策(decisions) | ||
| 49 | + | ||
| 50 | +本轮审阅未做改变源码语义的自主默认;对 D2/D7 的「装饰色豁免」「品牌 SVG 装饰填充非语义色」的判定均基于规格 D7 与原型逐字复刻证据,记录如下: | ||
| 51 | + | ||
| 52 | +- question: `LoginPage.tsx`/`Login.module.css` 中的 hex/rgba 是否构成 Design Token 违规? | choice: 不构成,判 approve | rationale: 全部位于主视觉装饰 / 品牌 Logo / ICP 图标 SVG / 阴影 alpha / 兜底常量,规格 D7 已豁免,且语义色无一硬编码 | confidence: high | ||
| 53 | +- question: 表单无 `<label>` 是否 must-fix? | choice: 否,降级为口头建议 | rationale: 原型即 placeholder-only 无 label 区,规格未要求可见标签,按 a11y best-effort 规则不单独触发 request-changes | confidence: high |