Files
wsmandClaude Opus 4.7 b5d3032f0c docs(xispeak): 归档前端页面 QA 审查报告并忽略 qa-tmp 临时产物
- qa-report/xispeak/QA_REPORT.md 提交入库(P0×1 / P1×4 / P2×5)
- .gitignore 忽略 qa-tmp/、__pycache__/、*.pyc,测试临时产物不入库

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

11 KiB
Raw Permalink Blame History

前端页面审查报告 — 习总书记重要讲话指示批示(xispeak)

审查信息

  • 页面/路由:/bg/xispeak/bgXiSpeakList(组件 src/views/bg/xispeak/BgXiSpeakList.vue
  • 审查日期:2026-08-07
  • 审查方式:frontend-page-qa skill 四阶段流程(代码静态审查 + Playwright 浏览器实测 + checklist 系统化走查)
  • 环境:dev 端口 3100(mock 开启),后端 http://localhost:8080/jeecg-boot,账号 admin/123456
  • 相关文件:
    • src/views/bg/xispeak/BgXiSpeakList.vue(树形列表 + 查询 + 流程操作)
    • src/views/bg/xispeak/BgXiSpeak.data.ts(列定义 + 高级查询)
    • src/views/bg/xispeak/BgXiSpeak.api.ts(接口层)
    • src/views/bg/xispeak/components/BgXiSpeakForm.vue(新增/编辑表单)
    • src/views/bg/xispeak/components/BgXiSpeakFeedbackForm.vue(反馈子表单)
    • src/views/bg/xispeak/components/BgXiSpeakBPMForm.vue(流程表单)
    • src/views/bg/xispeak/components/BgXiSpeakFeedbackViewModal.vue(查看办理情况)
    • src/views/bg/xispeak/components/BgXiSpeakFeedbackList.vue(孤儿组件)
    • 后端 backend/.../xispeak/controller/BgXiSpeakController.java

总体结论

  • P0 × 1 P1 × 4 P2 × 5
  • 一句话总结:核心 CRUD(新增→编辑→详情→删除)、查看办理情况、批量删除、导出均可用且无 console 错误;但存在 1 个功能性 P0(添加下级无法建立树层级,子记录退化为根记录)与 4 个 P1占位文本写入业务字段、多部门筛选语义错误、JBR 批量流程部分失败状态丢失、编辑反馈覆盖部门),不建议直接交付。

P0 - 必须修复

# 维度 问题描述 证据 位置
1 逻辑/操作顺序 "添加下级"无法创建子节点,树形层级功能整体失效。"添加下级"把 { pid: parentId } 传入表单,但 edit() 对无 id 的新记录直接重置 formData 并丢弃 pid,子记录以 pid='' 保存(后端落库为 pid="0"),变成平铺根记录;父节点永远不出现展开图标,无法构建层级。 实测 probe_pid.py:添加下级保存时 add 请求体 pid=""probe_tree.pyrootList 返回子记录 "pid":"0",父节点刷新前后均无展开图标,子行无缩进 BgXiSpeakForm.vue:255-262edit() 重置丢弃 pid)· 触发 BgXiSpeakList.vue:543-546 / :633

P1 - 强烈建议

# 维度 问题描述 证据 位置
1 逻辑/表单 占位模板文本被硬编码为表单默认值并写入业务字段。新增弹窗打开时"企业负责同志批示情况"已填 经单位主要负责同时签批同意,由xx部做好贯彻落实、"学习传达研究部署情况"已填 x月x日召开xxxx年第x次党委会议,提交时原样入库。用户不手动改就把占位假数据写进记录;同时这两个字段的必填校验形同虚设。 实测 probe_defaults.py:默认值截图 + 提交请求体 elmComment=经单位主要负责同时签批同意…, status=x月x日召开xxxx年第x次党委会议CRUD 回显列内容含占位文本 BgXiSpeakForm.vue:163-164
2 后端调用 牵头部门多选筛选为 AND 语义。前端把多个部门 id 逗号拼接成 implDept=A,B,后端在循环里逐个 queryWrapper.apply("FIND_IN_SET(...)"),生成 A AND B AND … 条件——一条记录必须同时包含所有选中部门才命中,选 2+ 部门时几乎查不到数据。应为 OR。 代码路径 BgXiSpeakController.java:94-102(循环 apply);前端拼接 BgXiSpeakList.vue:916-923 BgXiSpeakController.java:94-102
3 操作顺序 JBR 批量发起流程部分失败时状态不保存、列表不刷新successCount === total 守卫放在循环内,任一部门流程发起失败则 bpmStatus/supervisionCount 不更新、不 reload,已成功的流程成为"孤儿流程"且无部分成功提示。 probe_flows.py 未覆盖(需真实流程引擎);代码 BgXiSpeakList.vue:740-793 BgXiSpeakList.vue:783-787
4 状态一致性 编辑反馈记录时部门被当前登录人部门无条件覆盖edit() 加载记录后无条件调用 fillDeptFromLogin(),把 responDeptid/responDeptname 覆盖为登录人部门;跨部门编辑/审批他人的反馈并保存会造成部门归属数据错乱。 代码 BgXiSpeakFeedbackForm.vue:294 + 230-249 BgXiSpeakFeedbackForm.vue:294

P2 - 建议

# 维度 问题描述 证据 位置
1 性能/体验 搜索无防抖,逐字触发 rootList。JInput @change="searchQuery" 每个按键发一次查询;实测输入 6 个字符新增 6 次 rootList 请求。 probe_flows.py:输入前 rootList REQ=26 字符后=8 BgXiSpeakList.vue:12 + :900-902
2 安全/整洁 流程表单 14 处 console.log 调试输出,含 @props、流程变量、部门过滤中间结果等,生产环境泄漏调试信息。 代码 BgXiSpeakBPMForm.vue:311,312,596,603,607,612,618,624,627,659,662,664,671,686 BgXiSpeakBPMForm.vue14 处)
3 逻辑 反馈表单日期处理死代码 + 调试日志value.format('YYYY-MM-DD HH:mm:ss') 对 Date 对象调用 .format() 会抛 TypeError(当前 axios 返回字符串未触发,属潜在崩溃点);另有 3 处 console.log。 BgXiSpeakFeedbackForm.vue:281-289value.format);:238,243,248 BgXiSpeakFeedbackForm.vue:281-289
4 整洁 List.vue 死代码:未使用 import JDictSelectTag、未使用 computed showSdwLeaderSelect、未使用函数 handleFormJoinChange、line 142 import 缩进错乱。 全文件 grep 仅定义处出现 BgXiSpeakList.vue:148,202,937,142
5 整洁 孤儿组件 BgXiSpeakFeedbackList.vue 未被任何源码引用;searchReset() 调用 formRef.value.resetFields()formRef 未定义,一旦被挂载使用即崩溃。 BgXiSpeakFeedbackList.vue:141;全局 grep 仅 checklist 文档引用 BgXiSpeakFeedbackList.vue:141

通过项(做得好的地方)

  • CRUD 全链路正常:新增→保存→列表回显→编辑→详情→删除全部跑通,数据一致,无 console 错误。
  • 空表单校验:9 项必填错误准确提示并指向字段,提交前整体校验 + scrollToField 聚焦。
  • 危险操作二次确认:单条删除 Popconfirm(含"同时删除关联流程"说明文案)、批量删除 Modal.confirm,文案清晰。
  • 查看办理情况:动态标题"反馈信息(共 N 条,已完成 N 条)",空态显示"暂无数据",接口正常。
  • 批量删除:勾选→批量操作→确认→删除成功,选中后按 ids 传递。
  • 导出exportXls 请求正常发出并返回 200。
  • 接口契约add/edit/delete/rootList/statusStats/withDrawXiSpeak/queryFeedbackCounts 方法、URL、参数实测全部正确。
  • 权限控制:新增/导出/模板校验/模板导入等按钮均有 v-auth 指令;导出走配置 URL。
  • 列表列宽:长文本列均有 ellipsis,操作列 fixed: right 不换行。
  • 空响应兜底bgXiSpeakFeedbackList 无 mainId 时 Promise.resolve({}) 兜底,不崩溃(BgXiSpeak.api.ts:117-122)。

未覆盖项(需人工复核或真实环境验证)

  • 流程发起(发起落实措施收集流程 / 发起经办人执行反馈流程):需要真实 Flowable 引擎 + 部门审批人数据,本次未实测。JBR 部分失败场景据此推断代码逻辑,建议真实环境复测。
  • 树展开真实数据:DB 中无既有树形数据,且 P0(添加下级)导致无法生成层级,树展开仅验证到"无展开图标"。
  • 导出文件内容:headless 下导出经新窗口触发,仅确认请求 200,未核验 Excel 内容。
  • 上传类按钮(模板校验/模板导入/下载模板):未实测,依赖 /upload 代理(3300 端口本次未运行,产生 ERR_PROXY_CONNECTION_FAILED,与 xispeak 逻辑无关)。
  • 多分辨率/暗黑主题headless 固定 1440×900,视觉细节需人工复核。
  • 长文本/特殊字符(含 XSS)注入、大数据量、断网异常:未专项注入测试。
  • 双账号权限/密级过滤对比:仅使用 admin 单账号。

测试过程记录

操作步骤与截图

测试脚本与证据存于 qa-tmp/xispeak/(临时产物,gitignored;本报告为唯一提交的测试文档):

脚本 覆盖 截图/产物
probe_crud2.py 空表单校验 → 全字段填充 → 保存 → 列表回显 → 编辑 → 详情 → 删除 crud_test2/shots/*.png
probe_flows.py 查看办理情况 → 添加下级 → 搜索逐字输入(竞态)→ 清理 flows_test/shots/*.png
probe_extra.py 父/子记录创建 → 展开 → 督办状态筛选 → 导出 extra_test/shots/*.png
probe_batch2.py 勾选 → 批量删除 → 导出请求捕获 batch_test2/shots/*.png
probe_tree.py 添加下级后展开图标(刷新前后)→ rootList hasChild 字段 tree_test/shots/*.png
probe_pid.py 添加下级 add 请求体 pid 值 输出见运行记录
probe_defaults.py 新增弹窗默认值 + 空表单校验 + 提交入参 输出见运行记录
probe_secret.py / probe_fill*.py 密级/责任领导/部门选择弹窗结构 输出见运行记录

console 报错

  • xispeak 业务操作全程 0 个 error(各脚本 console.json)。
  • 唯一 error 为 ERR_PROXY_CONNECTION_FAILED:来自 /upload 代理(3300 端口 mock 服务未运行),与 xispeak 逻辑无关。

关键网络请求(probe_flows.py 汇总)

GET  /jeecgboot/bg/xispeak/bgXiSpeak/statusStats                   200
GET  /jeecgboot/bg/xispeak/bgXiSpeak/rootList                      200 (x10)
GET  /jeecgboot/bg/xispeak/bgXiSpeak/loadTreeRoot                  200 (x2)
GET  /jeecgboot/bg/xispeak/bgXiSpeak/queryFeedbackCounts           200 (x4)
POST /jeecgboot/bg/xispeak/bgXiSpeak/add                           200
GET  /jeecgboot/bg/xispeak/bgXiSpeak/listBgXiSpeakFeedbackByMainId 200
POST /jeecgboot/bg/xispeak/bgXiSpeak/withDrawXiSpeak               200
DELETE /jeecgboot/bg/xispeak/bgXiSpeak/delete                      200
GET  /jeecgboot/bg/xispeak/bgXiSpeak/exportXls                     200 (probe_batch2)

测试数据卫生

  • 所有测试数据使用 QA_TEST_ / QA_ / QA_BATCH / QA_DEFAULTS / QA_PARENT / QA_CHILD 前缀,测试后均通过 UI 删除清理(各脚本末步"清理"均归零)。无残留测试数据。