Commit c69d57be35202eea680d8e0e33833f8cc3b79838

Authored by zichun
1 parent 8a266615

docs(review:FE-03:r1): approve

docs/superpowers/reviews/2026-06-01-FE-03.md 0 → 100644
  1 +# FE-03 用户列表与查询 — AI 自审报告(round=1)
  2 +
  3 +> 阶段:前端(frontend)。审阅对象:`FE-03`(关联 `REQ-USR-003`,scope=usr)。
  4 +> 上游 spec:`docs/superpowers/specs/2026-06-01-FE-03.md`;上游 plan:`docs/superpowers/plans/2026-06-01-FE-03.md`。
  5 +> 关联原型:`prototype/erp.html` → `<section id="screen-userlist">`。
  6 +> Design Tokens SSoT:`src/styles/tokens.css`。API 契约:`docs/05-API接口契约.md § REQ-USR-003`。
  7 +> 审阅时间:2026-06-01。本报告由 fe-feature-review 渲染。
  8 +
  9 +---
  10 +
  11 +## 一、裁决
  12 +
  13 +**approve**(无 must-fix)。
  14 +
  15 +- 门禁回归(verify round=0):单测 138 passed / 0 failed;E2E 15 passed / 0 failed。
  16 +- reviewer 复核:`npm run lint` 干净;FE-03 新增 7 个单测文件本地复跑 50 passed / 0 failed(stderr 仅 jsdom `getComputedStyle` rc-table 非致命警告)。
  17 +- 作用域:全部改动落在 `frontend/`(含 docs/plans、docs/reviews),未触碰 `backend/` / `sql/` / `scripts/`,无越界。
  18 +
  19 +---
  20 +
  21 +## 二、通用四维
  22 +
  23 +### 计划一致性(plan-alignment)
  24 +- 组件树(页面容器 + UserToolbar / UserFilterBar / UserTable / UserPager 内置于 Table)与 spec § 2 / plan 文件边界一致。
  25 +- 列定义(序号 / 用户名 / 员工名 / 用户号 / 部门 / 用户类型 / 语言 / 作废 / 登录日期 / 制单人 / 制单日期)与 REQ 输出表 1 + 原型 thead 顺序一致(`columns.tsx`)。
  26 +- 业务规则 BR1–BR15 全部复刻(序号按当前页生成、作废只读 0/1→否/是、搜索回第 1 页、刷新保持当前页、清空重置默认、改页大小回第 1 页、行双击/新增导航、空态不报错、越界信任后端回显)。
  27 +- 自主决策 D1–D10 + D-PLAN-1/2 均落地(范围下拉占位不传参 D2、更多/齿轮占位 D3/D7、pageSize 默认 10 上限 100 D4、前端零依赖 CSV 导出 D5/D-PLAN-1、页面就近 hook D6、单选标记不参与查询 D8、中文键归一 D9/D-PLAN-2、工具栏深色局部装饰 D10)。
  28 +
  29 +### 质量(quality)
  30 +- 类型安全:`UserVO`/`PageResult<T>`/`UserListQuery` 契约清晰;`as unknown` 桥接仅用于拦截器已解包语义,与 FE-01/FE-02 既有约定一致。
  31 +- 错误处理:`useUserList.runFetch` 覆盖 42201(warning + 收敛分页重查)/ 40001(error + 保留条件不重查)/ 网络兜底(error + 错误占位重试);`ApiError` 分流文案与 spec § 4 错误码表逐条对齐。
  32 +- 健壮性:`mountedRef` 卸载守卫避免异步 resolve/reject 后 setState;`queryRef` 镜像避免闭包读旧值。
  33 +- 测试:状态机 6 态、各组件交互、CSV 导出、API 透传/归一均有单测 + E2E 固化。
  34 +
  35 +### 架构(architecture)
  36 +- 分层清晰:页面容器 / 子组件 / 列定义 / hook / api / 常量 / 导出工具各司其职。
  37 +- API 统一走 `frontend/src/api/request.ts` Axios 实例,方法集中于 `usrApi.ts listUsers`,页面不散用 axios(docs/04 § 2.3)。
  38 +- 列表查询态留在页面本地 hook,不进全局 store(docs/04 § 2.2 / D6)。
  39 +
  40 +### 文档(docs)
  41 +- 每文件首行带 `REQ-USR-003` 追溯注释 + BR/D 编号,符合 CLAUDE.md 注释约定。
  42 +- 无 TODO/TBD/人工填写占位残留。
  43 +
  44 +---
  45 +
  46 +## 三、前端 7 维 checklist
  47 +
  48 +| 维度 | 结论 | 说明 |
  49 +|---|---|---|
  50 +| 1 原型一致性 | PASS | toolbar(刷新/新增/导出Excel/spacer/齿轮)、filterbar(范围下拉/字段下拉/匹配下拉/查询值/▾/搜索/清空)、grid-table(11 列 + 单选首列)、pager(统计+上/下页+当前页+每页条数)与 `#screen-userlist` 结构逐块对应;主操作(搜索按钮)位置、列顺序、分页右对齐均一致。AntD 组件化为允许的实现差异。 |
  51 +| 2 Design Tokens | PASS | 语义/状态色(primary/error/warning/success/text/secondary/border/table-header/table-row hover/selected/form-bg)全部走 `var(--color-*)`;硬编码 `#2c2f36`/`#ffffff` 仅用于工具栏深色装饰底,为 spec § 7 / D10 显式登记的非语义局部装饰,与已 approve 的 FE-02 § 8 D9(topbar `#1f1f23` 等)同源精度,tokens.css 无对应工具条品牌色 token,不构成 token 违规。 |
  52 +| 3 无障碍 | PASS(best-effort) | 齿轮占位带 `aria-label="设置"`;筛选控件用 AntD `Select`/`Input`(无 spec 要求的强制 label,原型亦无);危险/不可逆操作本页不存在(只读查询)。对比度为主观项,无明显失败。 |
  53 +| 4 响应式 | PASS(best-effort) | 表格 `scroll={{ x:'max-content' }}` 复刻原型横向滚动;filterbar `flex-wrap`;无明显横向溢出或 hover-only 关键操作。 |
  54 +| 5 业务校验前端复刻 | PASS | 查询字段/匹配方式枚举受限于 `Select` 合法项(BR4);查询值空为全部(BR3,listUsers 省略空 `queryValue`);默认值预填(BR2);错误码文案与后端语义一致(spec § 4)。 |
  55 +| 6 API 调用一致性 | PASS | `GET /usr/users`(baseURL=/api → `/api/usr/users`)与 docs/05 路径一致;query 字段 `queryField/matchType/queryValue/pageNum/pageSize` 与契约一致;`UserVO` 字段与契约一致(中文键 `员工名`/`部门` 在 api 层归一为 `employeeName`/`departmentName`,D9);统一客户端,无裸 fetch/axios。 |
  56 +| 7 状态机覆盖 | PASS | loading(初始 `useState(true)` + 取数中)/ empty(AntD `Empty`「暂无匹配的用户」)/ error(errorBox + 点击重试)/ 正常(表格行)/ 提交中(exporting:导出按钮 loading+disabled)五态俱全。 |
  57 +
  58 +---
  59 +
  60 +## 四、非阻塞建议(不计入 must-fix)
  61 +
  62 +- **导出上限**:`useUserList.exportExcel` 将 `fetchSize` 收敛至 `≤100`(`Math.min(Math.max(total, pageSize, 1), 100)`),当 `total>100` 时仅导出前 100 行。此为 spec D5(confidence=medium,「MVP 阶段前端导出 … 一次或分批取」)显式登记的取舍,未做分页循环属已记录的 MVP 简化,非 spec 违规。后续若后端补 `/export` 端点或需求要求全量导出,可改为按页循环取。建议在用户量级增长后跟进,不阻塞本轮。
  63 +- 工具栏深色装饰底(`#2c2f36`)目前在 `UserList.module.css` 与 FE-02 `AppLayout.module.css`(`#1f1f23`)各自硬编码。若后续多处工具条深色趋于一致,可考虑提一个非语义装饰变量集中管理;当前各页局部化处理与已批准的 FE-02 决策一致,不强制。
  64 +
  65 +---
  66 +
  67 +## 五、结论
  68 +
  69 +实现忠实复刻原型布局与交互语义,真实对接 `GET /api/usr/users`,状态机完整、错误码分流到位、tokens 使用规范、API 契约一致、作用域无越界,门禁与 lint 全绿。无客观可验证的 must-fix 缺陷。
  70 +
  71 +**verdict = approve**
... ...