2026-06-01-FE-03.md 6.53 KB

FE-03 用户列表与查询 — AI 自审报告(round=1)

阶段:前端(frontend)。审阅对象:FE-03(关联 REQ-USR-003,scope=usr)。 上游 spec:docs/superpowers/specs/2026-06-01-FE-03.md;上游 plan:docs/superpowers/plans/2026-06-01-FE-03.md。 关联原型:prototype/erp.html<section id="screen-userlist">。 Design Tokens SSoT:src/styles/tokens.css。API 契约:docs/05-API接口契约.md § REQ-USR-003。 审阅时间:2026-06-01。本报告由 fe-feature-review 渲染。


一、裁决

approve(无 must-fix)。

  • 门禁回归(verify round=0):单测 138 passed / 0 failed;E2E 15 passed / 0 failed。
  • reviewer 复核:npm run lint 干净;FE-03 新增 7 个单测文件本地复跑 50 passed / 0 failed(stderr 仅 jsdom getComputedStyle rc-table 非致命警告)。
  • 作用域:全部改动落在 frontend/(含 docs/plans、docs/reviews),未触碰 backend/ / sql/ / scripts/,无越界。

二、通用四维

计划一致性(plan-alignment)

  • 组件树(页面容器 + UserToolbar / UserFilterBar / UserTable / UserPager 内置于 Table)与 spec § 2 / plan 文件边界一致。
  • 列定义(序号 / 用户名 / 员工名 / 用户号 / 部门 / 用户类型 / 语言 / 作废 / 登录日期 / 制单人 / 制单日期)与 REQ 输出表 1 + 原型 thead 顺序一致(columns.tsx)。
  • 业务规则 BR1–BR15 全部复刻(序号按当前页生成、作废只读 0/1→否/是、搜索回第 1 页、刷新保持当前页、清空重置默认、改页大小回第 1 页、行双击/新增导航、空态不报错、越界信任后端回显)。
  • 自主决策 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)。

质量(quality)

  • 类型安全:UserVO/PageResult<T>/UserListQuery 契约清晰;as unknown 桥接仅用于拦截器已解包语义,与 FE-01/FE-02 既有约定一致。
  • 错误处理:useUserList.runFetch 覆盖 42201(warning + 收敛分页重查)/ 40001(error + 保留条件不重查)/ 网络兜底(error + 错误占位重试);ApiError 分流文案与 spec § 4 错误码表逐条对齐。
  • 健壮性:mountedRef 卸载守卫避免异步 resolve/reject 后 setState;queryRef 镜像避免闭包读旧值。
  • 测试:状态机 6 态、各组件交互、CSV 导出、API 透传/归一均有单测 + E2E 固化。

架构(architecture)

  • 分层清晰:页面容器 / 子组件 / 列定义 / hook / api / 常量 / 导出工具各司其职。
  • API 统一走 frontend/src/api/request.ts Axios 实例,方法集中于 usrApi.ts listUsers,页面不散用 axios(docs/04 § 2.3)。
  • 列表查询态留在页面本地 hook,不进全局 store(docs/04 § 2.2 / D6)。

文档(docs)

  • 每文件首行带 REQ-USR-003 追溯注释 + BR/D 编号,符合 CLAUDE.md 注释约定。
  • 无 TODO/TBD/人工填写占位残留。

三、前端 7 维 checklist

维度 结论 说明
1 原型一致性 PASS toolbar(刷新/新增/导出Excel/spacer/齿轮)、filterbar(范围下拉/字段下拉/匹配下拉/查询值/▾/搜索/清空)、grid-table(11 列 + 单选首列)、pager(统计+上/下页+当前页+每页条数)与 #screen-userlist 结构逐块对应;主操作(搜索按钮)位置、列顺序、分页右对齐均一致。AntD 组件化为允许的实现差异。
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 违规。
3 无障碍 PASS(best-effort) 齿轮占位带 aria-label="设置";筛选控件用 AntD Select/Input(无 spec 要求的强制 label,原型亦无);危险/不可逆操作本页不存在(只读查询)。对比度为主观项,无明显失败。
4 响应式 PASS(best-effort) 表格 scroll={{ x:'max-content' }} 复刻原型横向滚动;filterbar flex-wrap;无明显横向溢出或 hover-only 关键操作。
5 业务校验前端复刻 PASS 查询字段/匹配方式枚举受限于 Select 合法项(BR4);查询值空为全部(BR3,listUsers 省略空 queryValue);默认值预填(BR2);错误码文案与后端语义一致(spec § 4)。
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。
7 状态机覆盖 PASS loading(初始 useState(true) + 取数中)/ empty(AntD Empty「暂无匹配的用户」)/ error(errorBox + 点击重试)/ 正常(表格行)/ 提交中(exporting:导出按钮 loading+disabled)五态俱全。

四、非阻塞建议(不计入 must-fix)

  • 导出上限useUserList.exportExcelfetchSize 收敛至 ≤100Math.min(Math.max(total, pageSize, 1), 100)),当 total>100 时仅导出前 100 行。此为 spec D5(confidence=medium,「MVP 阶段前端导出 … 一次或分批取」)显式登记的取舍,未做分页循环属已记录的 MVP 简化,非 spec 违规。后续若后端补 /export 端点或需求要求全量导出,可改为按页循环取。建议在用户量级增长后跟进,不阻塞本轮。
  • 工具栏深色装饰底(#2c2f36)目前在 UserList.module.css 与 FE-02 AppLayout.module.css#1f1f23)各自硬编码。若后续多处工具条深色趋于一致,可考虑提一个非语义装饰变量集中管理;当前各页局部化处理与已批准的 FE-02 决策一致,不强制。

五、结论

实现忠实复刻原型布局与交互语义,真实对接 GET /api/usr/users,状态机完整、错误码分流到位、tokens 使用规范、API 契约一致、作用域无越界,门禁与 lint 全绿。无客观可验证的 must-fix 缺陷。

verdict = approve