Files
wsmandClaude Opus 4.7 8b2a0255c0 docs(fixcontact): 归档前端页面 QA 审查报告
浏览器实测 + 代码审查,P0×0 / P1×2 / P2×4。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-07 16:24:10 +08:00

103 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端页面审查报告 — fixcontact(定点联系单)
## 审查信息
- 页面/路由:`/bg/fixcontact/FixedContact20260730List`
- 审查日期:2026-08-07
- 审查方式:浏览器实测(Playwrightadmin/123456+ 代码静态审查
- 测试环境:前端 dev `http://127.0.0.1:3100`,后端 `http://localhost:8080/jeecg-boot`,登录走 mock、其余接口走真实后端
- 相关文件:
- `src/views/bg/fixcontact/FixedContact20260730List.vue`
- `src/views/bg/fixcontact/components/FixedContact20260730Form.vue`
- `src/views/bg/fixcontact/components/FixedContact20260730Modal.vue` / `BPMForm.vue` / `BPMFeedbackModal.vue`
- `src/views/bg/fixcontact/FixedContact20260730.api.ts`
- 依赖组件:`JInput``SzSelectDept``DeptRoleUserSelectDropDown``JFormContainer``FlowScheduleStartModalForBG``BusinessProcessListModal`
- 测试证据目录:`qa-tmp/fixcontact/artifacts/<probe>/`(截图 / console.json / requests.json
## 总体结论
- **P0 × 0 P1 × 2 P2 × 4**
- 一句话总结:页面核心功能(增删改查、详情只读、批量删除、导出/模板、流程入口、反馈子表、统计标签)均可用,无 P0;存在 2 个 P1 影响体验与数据完整性(搜索逐字符发请求、`是否所办领导审批=是` 时审批人可留空),建议交付前修复。
---
## P1 - 强烈建议
| # | 维度 | 问题描述 | 证据 | 位置 |
|---|------|---------|------|------|
| 1 | 后端调用/性能 | 表单编号搜索框**逐字符触发查询**,每敲一个字符发 1 次列表请求 + 1 次统计请求,无防抖/回车确认。实测输入 5 个字符共发出 5 list + 5 statusStats 请求(每个字符 2 个接口)。查询输入框直接绑定 `@update:value="searchQuery"`,而 `JInput` 每次敲键都会 emit `update:value`。 | probe_12 A 段输出:`after typing 'QA' (2 chars): list=2 stats=2``after typing full 'QA001' (5 chars): list=3 stats=3`;截图 `12_search_flood_pagination/` | `FixedContact20260730List.vue:12``@update:value="searchQuery"`);`JInput.vue` emit `update:value` |
| 2 | 表单校验/状态一致性 | **联动校验缺位**`是否所办领导审批=是`isNeedAppro='1')时 `所办领导`supDeptleaderid)字段解除禁用,但 `validatorRules` 中**没有该字段的校验规则**,可留空提交。实测:填满其余必填、`是` + 空审批人提交 → 无校验错误,创建成功,请求体为 `"isNeedAppro":"1","supDeptleaderid":""`。该记录随后发起流程时审批人为空,审批任务可能无人办理。 | probe_14 输出:`VALIDATION ERRORS: []``TOASTS: ['添加成功!']`、add body 含 `"isNeedAppro":"1","supDeptleaderid":""`;截图 `14_isneed_submit/` | `FixedContact20260730Form.vue:91-99``:disabled="formData.isNeedAppro !== '1'"`)、`FixedContact20260730Form.vue:158-171`validatorRules 无 supDeptleaderid |
---
## P2 - 建议
| # | 维度 | 问题描述 | 证据 | 位置 |
|---|------|---------|------|------|
| 1 | 后端调用 | `handleFlowScheduleConfirm``startProcessSchedules``try/catch`、不校验返回值,成功后无条件 `createMessage.success('发起成功')`。当前依赖框架默认 transform(失败即抛错并弹框架错误提示)故不会误报成功,但属于隐性依赖,建议显式 `try/catch` + 检查 `res.success`。 | 代码审查 | `FixedContact20260730List.vue:578-626` |
| 2 | 用户体验/冗余 | 工具栏同时存在旧 `导入`onImportXls→importExcel)与新增 `模板导入`handleImportByTemplate→importExcelByEasyExcel)、`模板校验`,同一导入能力出现两个入口,易混淆。另 `handleDownloadTemplate` 复用的 `getExportXlsHeadersUrl` 命名与语义不符(实际为模板下载,非导出表头)。 | 代码审查;截图 `10_toolbar_export_expand/a_`… | `FixedContact20260730List.vue:101-105, 639` |
| 3 | 异常与边界 | `handleDownloadTemplate`:仅 `if (!data)` 提示下载失败,网络异常(请求 reject)时无兜底提示(未捕获的 Promise rejection)。 | 代码审查 | `FixedContact20260730List.vue:639-651` |
| 4 | 渲染/console | 使用 fixcontact 页面期间 console 出现框架级告警:①`Invalid prop: type check failed for prop "onClick"/"onChange"`96 次,来自 VcSelect/BaseSelect/DeptRoleUserSelectDropDown 向组件传数组型事件);②`Property "interUserSecurityLevel" was accessed during render but is not defined`(渲染时访问未定义属性);③全局头部 `Failed to resolve component: AppSearch/Notify/...`。均为框架/全局布局噪声,非本模块引入,但 ①② 建议顺手清理。 | `09_toast_detail_batch/console.json``10_toolbar_export_expand/console.json` | 表单组件渲染链路 |
---
## 通过项(做得好的地方)
- **CRUD 全链路正确**:新增(add POST 请求体字段完整)→ 列表回显 → 编辑(edit POST 带 id、字段更新)→ 详情(标题"详情")→ 单删(popconfirm 二次确认)均正常,操作后列表与统计标签同步刷新。
- **详情只读实现正确**:详情态表单整体只读(`JFormContainer` 施加 `.jeecg-form-container-disabled` + `fieldset { pointer-events: none }`),实测详情态输入框 `pointer-events: none`、无法编辑(早期"详情未禁用"怀疑不成立,实测为只读)。
- **无重复提交/重复 toast**:新增仅发 1 次 POST、仅弹 1 次"添加成功!"(早期"重复 toast"观察为前一条消息残留,已排除)。
- **批量删除**:勾选多行 → 批量操作 → 删除 → 确认弹窗 → 批量删除成功(实测 3 条一次删净)。
- **统计标签**`未开始 4 / 督办中 1(已逾期 0)/ 已完成 0` 正确渲染,由 statusStats 接口驱动。
- **导入导出/模板**`导出`GET exportXls)、`下载模板`GET exportXlsHeaders)均正常触发下载。
- **反馈子表**:行展开后按主表 id 调用 `queryFixedContactFeedback20260730ByMainId` 加载反馈记录(实测无数据时正确显示"共 0 条")。
- **流程入口**`流程操作` 下拉(发起流程 / 查询督办流程)正常;`发起流程` 弹窗(标题"发起流程",含"取消/提交"),`查询督办流程` 弹窗(标题"流程列表")正常展示已发起调度记录。
- **字段联动(显隐)**`是否所办领导审批` 切换 `是/否``所办领导` 选择器正确解除/恢复禁用(仅缺联动校验,见 P1-2)。
- **搜索筛选**:表单编号、联系单位(部门树选择器)筛选生效,列表请求正确携带 `contactDept[]` 参数;重置清空条件并刷新。
- **分页**`共 5 条数据`、页大小 12/24/36 可选、切页大小正常触发列表刷新。
- **表单必填校验**:12 个必填字段在提交时整体校验并定位错误字段(probe_08b 实测)。
- **权限指令**:新增/导出/导入/模板校验/模板导入/批量删除按钮均带 `v-auth` 权限控制。
---
## 未覆盖项(仅 1 个测试账号 admin)
- **权限差异**:非管理员/不同部门账号下按钮显隐、数据范围(后端过滤)无法用 1 个账号验证,`v-auth` 仅确认指令存在。
- **接口越权(IDOR**:改 `id` 访问他人数据是否被后端拦截未验证(前端未暴露此类入口)。
- **纯视觉细节**:当前环境模型无法直接查看截图,对齐/间距/配色/空态图等视觉项以 DOM 结构 + getComputedStyle 评估,需人工复核 `qa-tmp/fixcontact/artifacts/*/*.png`
- **多视图一致性**:本列表页无平铺/分组等其他视图,无跨视图数据同步场景。
- **深链接/浏览器前进后退**:未覆盖。
---
## 测试过程记录
测试脚本:`qa-tmp/fixcontact/scripts/probe_0{1..15}_*.py`(共享助手 `_fx_helpers.py`)。
证据根目录:`qa-tmp/fixcontact/artifacts/`
| Probe | 覆盖内容 | 关键结果 | 证据目录 |
|-------|---------|---------|---------|
| 01-05 | 路由可达、列表加载、接口契约、渲染诊断、弹窗映射 | 页面正常进入,list/statusStats 接口可用 | `01_login_route``05_modal_map` |
| 06 | 校验 + 下拉选择 | 必填校验生效、领导下拉可选 | `06_validation_selects` |
| 07 | 选择器(部门/用户/领导/日期) | 选择器均可提交值(部门树需勾选 checkbox,见下) | `07_pickers` |
| 08 | CRUD 全链路 | 增删改查+详情全部通过,add/edit POST body 正确 | `08_crud` |
| 08b/08c | 表单值诊断、部门选择器调试 | 确认 SzSelectDept 取值依赖树 checkbox 勾选(测试脚本问题,非页面 bug) | `08b_fill_diag``08c_dept_debug` |
| 09 | 重复 toast / 详情只读 / 流程菜单 / 批量删除 | 单 toast 单 POST;详情只读正确;发起流程+流程列表弹窗正常;批量删除成功 | `09_toast_detail_batch` |
| 10 | 导出/模板/反馈子表展开/是审批切换/高级查询 | 导出、下载模板、反馈子表、是/否切换均正常;高级查询面板可打开 | `10_toolbar_export_expand` |
| 11 | 是审批切换细节/反馈子表稳定/高级查询 | 所办领导禁用⇄启用切换正确;反馈子表"共 0 条";高级查询面板含"执行查询/保存查询/清空/关闭" | `11_isneed_expand_superq` |
| 12 | 搜索请求数/重置/分页 | **逐字符 1 次 list+1 次 stats**(P1-1);重置清空;分页 12/24/36 正常 | `12_search_flood_pagination` |
| 13 | 搜索区联系单位部门筛选 | 树弹窗选择后列表携带 `contactDept[]` 参数 | `13_dept_filter` |
| 14 | isNeedAppro=是 + 空审批人提交 | **校验放行,创建成功,supDeptleaderid 为空**P1-2 | `14_isneed_submit` |
| 15 | 测试数据清理 | 删除全部 `QA_TST_/QA_APPRO_` 前缀测试数据 | `15_cleanup` |
### console 告警汇总(均为框架级噪声,无本模块 app error)
- 96× `Invalid prop: type check failed for prop "onClick"/"onChange"`VcSelect/BaseSelect 系列)
- 6× `Property "interUserSecurityLevel" was accessed during render but is not defined`
- 若干 `Failed to resolve component: AppSearch/Notify/AppLocalePicker/SettingDrawer/Aide`(全局头部组件)
- 其余为应用启动日志与 `sign requestBody` 请求签名日志
### 残留/预存数据说明
- 测试过程中创建并已清理的 QA_ 数据:`QA_TEST_*``QA_TST_*``QA_APPRO_*`probe_15 确认全部删除)。
- 列表中存在一条**预存测试脏数据**:`formNo="new"``meetingPlace="w'da'w"`、创建时间 2026-08-07 15:45:38,非本次测试产生,**未删除**,建议人工确认是否需要清理。