2026-06-01-FE-01.md
6.11 KB
FE-01 登录页 — AI 自审报告(第 1 轮)
- 阶段:前端(frontend)
- 关联 REQ:REQ-USR-004(主);配套
GET /api/usr/companies - 关联原型:
prototype/erp.html→<section id="screen-login"> - 规格:
docs/superpowers/specs/2026-06-01-FE-01.md - 裁决:approve
- must-fix issues:无(空数组)
审阅范围
本轮 diff(自 2dce637^ 起的 FE-01 提交链)落在 frontend/ 内,作用域合规,未触碰 backend/ / sql/ / scripts/。核心文件:
frontend/src/pages/usr/Login/LoginPage.tsxfrontend/src/pages/usr/Login/Login.module.cssfrontend/src/pages/usr/Login/loginMessages.tsfrontend/src/api/{request.ts,types.ts,usrApi.ts}-
frontend/src/store/slices/authSlice.ts、frontend/src/router/index.tsx、frontend/src/App.tsx、frontend/src/styles/theme.ts
质量闸(独立复跑验证)
-
tsc --noEmit:通过(exit 0)。 -
vitest run:10 文件 / 32 用例全绿(含布局、版本预加载/空态/重试、校验、提交中态、错误码分流、成功落地、authSlice、request 拦截器)。 -
eslint .:通过(exit 0)。
前端 7 维 checklist
-
原型一致性(客观)— 通过:复刻
.login-wrap三段式(品牌头 / 深蓝主视觉+右侧浮层登录卡 / 页脚版权);登录卡right:8% top:50% translateY(-50%)、宽 380px、主操作为底部block主按钮,与原型 DOM 结构与主操作位置一致。下拉以 AntDSelect等价复刻原型.lf.dropdown,属允许的实现差异。 -
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」)。 -
无障碍(best-effort):表单控件仅用
placeholder,无显式<label>/aria-label——但原型本身即 placeholder-only 无 label 区,规格未要求可见标签,故按 best-effort 处理,不作 must-fix(建议项见下)。装饰 SVG 正确带aria-hidden;无危险/不可逆操作,无需确认弹窗;支持回车提交(AntD Form 默认),键盘可达。 -
响应式(best-effort):
@media (max-width:768px)将卡片回流为居中静态布局(D4)。目标用户为桌面端 ERP,无 must-fix。 -
业务校验前端复刻(客观)— 通过:BR1/BR2/BR4 用 AntD
Form必填校验(文案「请输入用户名」「请输入密码」「请选择版本」);BR3Input.Password掩码;BR6/BR7/BR8 错误码 40101/40302/42901 文案与后端语义一致且不细化枚举;BR9 成功落地;BR10submitting期间禁用+早返回防重复提交;BR11 明文原样提交。 -
API 调用一致性(客观)— 通过:
POST /api/usr/login、GET /api/usr/companies均经统一request.tsAxios 实例,无裸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。 -
状态机覆盖(客观)— 通过:5 态齐备——
companiesLoading(Selectloading+禁用+占位「加载版本中…」)、idle、empty(notFoundContent="暂无可用版本"+轻提示)、submitting(按钮 loading + Form 整体disabled+ 早返回)、error(错误码分流message.error+ 版本失败重试入口)、success(setCredentials+ 持久化 +navigate('/',{replace:true}))。
通用四维
- 计划对齐:实现与 spec §2-§7 / REQ-USR-004 输入表逐项对应,自主决策 D1-D8 在代码注释与结构中可追溯。
- 质量:错误处理集中在响应拦截器 + 页面错误码映射;TS 类型契约(
types.ts)跨 task 共享;测试覆盖充分;登录端点放行、token 仅登录态注入,无明显安全/性能问题。 - 架构:api / store / pages / router / styles 分层清晰,页面只调
usrApi,不散用 axios;token 持久化键TOKEN_STORAGE_KEY单点定义。 - 文档:文件含
REQ-USR-004注释与决策追溯,符合 CLAUDE.md 约定。
非阻塞建议(口头,不入 issues)
- A11y 增强(建议):可为用户名 / 密码 / 版本三控件补
aria-label(如「用户名」「密码」「版本」),在 placeholder-only 布局下提升读屏可用性。非 must-fix。 -
authSlice.setCredentialsreducer 内做localStorage写副作用为 MVP 取舍(D6 已登记),后续如引入 SSR/严格纯 reducer 规范可迁至中间件或 thunk。非本轮阻塞。
决策(decisions)
本轮审阅未做改变源码语义的自主默认;对 D2/D7 的「装饰色豁免」「品牌 SVG 装饰填充非语义色」的判定均基于规格 D7 与原型逐字复刻证据,记录如下:
- question:
LoginPage.tsx/Login.module.css中的 hex/rgba 是否构成 Design Token 违规? | choice: 不构成,判 approve | rationale: 全部位于主视觉装饰 / 品牌 Logo / ICP 图标 SVG / 阴影 alpha / 兜底常量,规格 D7 已豁免,且语义色无一硬编码 | confidence: high - question: 表单无
<label>是否 must-fix? | choice: 否,降级为口头建议 | rationale: 原型即 placeholder-only 无 label 区,规格未要求可见标签,按 a11y best-effort 规则不单独触发 request-changes | confidence: high