docs(fixcontact): 归档前端页面 QA 审查报告
浏览器实测 + 代码审查,P0×0 / P1×2 / P2×4。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# 前端页面审查报告 — fixcontact(定点联系单)
|
||||
|
||||
## 审查信息
|
||||
|
||||
- 页面/路由:`/bg/fixcontact/FixedContact20260730List`
|
||||
- 审查日期:2026-08-07
|
||||
- 审查方式:浏览器实测(Playwright,admin/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,非本次测试产生,**未删除**,建议人工确认是否需要清理。
|
||||
Reference in New Issue
Block a user