浏览器实测 + 代码审查,P0×0 / P1×2 / P2×4。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
10 KiB
10 KiB
前端页面审查报告 — 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.vuesrc/views/bg/fixcontact/components/FixedContact20260730Form.vuesrc/views/bg/fixcontact/components/FixedContact20260730Modal.vue/BPMForm.vue/BPMFeedbackModal.vuesrc/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,非本次测试产生,未删除,建议人工确认是否需要清理。