Files
supervision-test-frontend-repo/qa-report/inspectTask/QA_REPORT.md
T
wsm 237a5810cf !145 docs(xispeak): 归档前端页面 QA 审查报告(用户视角)
* docs(xispeak): 归档前端页面 QA 审查报告(用户视角)
* docs(fixcontact): 归档前端页面 QA 审查报告(用户视角)
* docs(inspectTask): 归档前端页面 QA 审查报告(工程师+用户视角)
* docs(bqtakepulse): 归档前端页面 QA 审查报告(工程师+用户视角)
* docs(bgpartymatter): 归档前端页面 QA 审查报告(工程师+用户视角)
2026-08-11 07:27:58 +00:00

18 KiB
Raw Blame History

前端页面审查报告 — 巡视整改提升工作台账(DqInspectTaskList

审查信息

  • 页面/路由:/dq/inspectTask/DqInspectTaskList(巡视整改提升工作台账)
  • 审查日期:2026-08-11
  • 审查视角:资深前端工程师(浏览器实测 + 代码审查结合)
  • 审查账号:admin(mock 登录,其余接口打真实后端 8080)
  • 相关文件:
    • src/views/dq/inspectTask/DqInspectTaskList.vue
    • src/views/dq/inspectTask/components/DqInspectTaskForm.vueDqInspectTaskModal.vueDqInspectTaskFlowScheduleStartModal.vue
    • src/views/dq/inspectTask/DqInspectTask.data.tsDqInspectTask.api.ts
    • src/components/semri/userComponent/DeptRoleUserSelectDropDown.vue
    • src/components/Modal/src/BasicModal.vuesrc/components/Modal/src/components/ModalClose.vue
    • 后端契约:jeecg-module-supervision/.../DqInspectTaskController.javaDqInspectTaskMapper.xmljeecg-module-system/.../tasktask/TaskTaskController.javaTaskTaskServiceImpl.java
  • 证据目录:qa-tmp/inspectTask/(截图 screenshots/、脚本/记录 scripts/artifacts/
  • 关联报告:qa-report/inspectTask/QA_REPORT_UX.md(用户视角,可并列对比)

总体结论

  • P0 × 1 P1 × 4 P2 × 7
  • 一句话总结:核心增删改查/详情/流程查看可走通,但整改措施搜索框完全失效(P0——后端 ledger 自定义 SQL 对前端 *like* 通配符二次包裹导致永远查不到、清空也不恢复;另有责任领导列误绑/详情占位符(共享组件 watch 清值竞态)、流程操作不随状态且后端无守卫、分管所领导筛选被列表忽略等 4 个 P1,不建议按当前状态交付,需先修复 P0。

P0 - 必须修复

# 维度 问题描述 证据 位置
1 后端调用/功能错误 「整改措施」搜索框完全失效。列表页 JInput type="like" 把输入值包装成 *wqdwqd* 发到后端,但后端台账自定义 SQL 又做了一次 concat('%', value, '%'),实际生成 improve_measure like '%*wqdwqd*%'——带字面量星号,任何真实值都匹配不到,搜索永远返回 0 行;清空输入框时发送 improveMeasure=**(空值仍被包一层星号)→ 列表继续保持空,直到点「重置」。期间顶部统计标签仍显示「督办中 1」,列表(0) 与统计(1) 自相矛盾,用户误以为数据丢了。 实测 artifacts/eng_02_api_bodies.jsonledgerList?improveMeasure=wqdwqd → records:[] total:0,同参数 statusStats → inProgress:1);实测 artifacts/eng_10_search_bug.json(输入 wqdwqd → row_count:0;清空 → 请求 improveMeasure=** 仍 0 行);截图 screenshots/eng_15_final_list.png 前端 DqInspectTaskList.vue:9JInput type="like" @change="reload");后端 DqInspectTaskMapper.xml:50-52t.improve_measure like concat('%', #{task.improveMeasure}, '%')

技术根因DqInspectTaskMapper.xmlqueryLedgerPage 是手写 SQL,它的 like 分支假定前端传普通值;而 JInput type="like" 走 Jeecg QueryGenerator 的 *...* 约定传通配符。两者叠加 = 二次包裹。statusStats 接口用 QueryGenerator 直查实体(*% 正确转换)所以能匹配,于是列表与统计对同一筛选结果不一致。 修复建议:二者取其一——(a) 前端 DqInspectTaskList.vue:9 去掉 type="like"(改普通输入,由 XML concat('%',…,'%') 负责模糊);或 (b) 后端 XML 把值里的 * 转成 % 再包裹,并兜底空值时不发该条件(避免 **)。建议同时做 (b) 的空值判断,彻底解决"清空后列表空"。


P1 - 强烈建议修复

# 维度 问题描述 证据 位置
1 逻辑/数据显示 列表「措施责任领导」列误绑 measureResDept_dictText:该列与「措施责任部门」列显示完全相同的部门名「DD」,真实责任领导 dd_ld_02 看不到。后端已正确返回 measureResLeader_dictText=dd_ld_02 实测 artifacts/eng_01_rows.json(第 7、8 列均为 "DD");artifacts/eng_02_api_bodies.jsonledgerList 响应含 measureResLeader_dictText=dd_ld_02);截图 04_list.png DqInspectTask.data.ts:255-258(措施责任领导列 dataIndex: 'measureResDept_dictText',应为 'measureResLeader_dictText'
2 状态一致性/竞态 详情/编辑弹窗「措施责任领导」显示占位符「请选择措施责任领导」:后端已赋值 measureResLeader=dd_ld_02 且该下拉能查到 dd_ld_02,但 select 值为空。根因是 DeptRoleUserSelectDropDown 的 watch 在 deptId/roleId 变化时无条件 modelValue.value = '':详情加载先赋 measureResDeptmeasureResDeptId computed 变化 → watch 触发 → 把刚加载的 measureResLeader 清掉(数据加载与 watch 的竞态)。因 measureResLeader 是动态 deptId,全表单只有它中招;chargeLeaderId 的 deptId 是静态常量不触发 watch,故正常。编辑模式同路径也会被清空(必填校验会拦下提交,不致静默丢数据,但每次编辑都要重选)。 实测 artifacts/eng_09_leader_rootcause.jsonqueryUserRoleComponentData 对 measureResLeader 下拉返回 records 含 dd_ld_02 has_dd_ld_02:true,但 select value_input:""selection_items:[]、placeholder_shown:true;对照 chargeLeader_selection:["所领导01"] 正常);artifacts/probe_querybyid.jsonqueryById.result.measureResLeader=dd_ld_02);截图 eng_09_detail_modal.png60_detail_values.png src/components/semri/userComponent/DeptRoleUserSelectDropDown.vue:63-69watch(() => [props.deptId, props.roleId], () => { modelValue.value = ''; fetchUserList(); }));使用处 DqInspectTaskForm.vue:86-92:deptId="measureResDeptId" 动态)
3 状态流转/后端调用 流程操作菜单不随任务状态变化,督办中任务也能「发起巡视整改流程/发起销号流程」→ 有创建重复/错误流程实例风险。前端 getFlowMenuList 按状态显隐的 if 全被注释掉(388-421 行),所有记录都展示两个发起项;实测督办中(bpmStatus=2, completedStage=1)记录两项均可见、弹窗可打开。后端 singleFlowStart 无任何业务状态守卫validateBusinessParams 只校验 flowCode/businessId/formUrl 非空,提交会无条件新建 TaskTask 并 startMutilProcess 启动新 Flowable 流程实例。为保护真实流程数据未点「提交」,创建重复实例为代码确认+实测入口,未实测触发 实测 artifacts/eng_06_flow.json(督办中记录 flow_menu_items=[发起巡视整改流程,发起销号流程,查询督办流程];弹窗可打开);后端代码 TaskTaskServiceImpl.java:55-75,133-152singleFlowStart 无守卫、validateBusinessParams 仅非空校验);TaskTaskController.java:127-140flow-schedules 无业务状态校验) 前端 DqInspectTaskList.vue:388-421getFlowMenuList,条件判断被注释);发起 handleFlowScheduleConfirm 491-524 行;后端 TaskTaskServiceImpl.singleFlowStart
4 后端调用/状态一致性 查询筛选对台账列表部分失效:分管所领导筛选被列表忽略,且统计与列表不一致。自定义 SQL queryLedgerPage 只实现了 improveMeasure/measureResLeader/measureResDept/problemId/completedStage/bpmStatus 6 个字段的子句,没有 charge_leader_id 子句;实测筛选「分管所领导=所党委01(无该领导记录)」列表仍显示全部 2 行(筛选被吞),而 statusStats 用 QueryGenerator 会应用该条件 → 统计归零、列表全量,自相矛盾。同机制下,高级查询暴露的 19 个字段里 13 个(targetNode/deadline/secretLevel 等)在列表侧同样无效(代码推断,与 chargeLeader 同路径)。 实测 artifacts/eng_11_cleanup_filters.jsonfilter_chargeLeader_sdw01 → row_count:2,筛选被忽略);后端 DqInspectTaskMapper.xml:49-68<if test> 仅 6 个字段);DqInspectTaskController.java:98-107ledgerList 透传 QueryGenerator 生成的实体条件) 后端 DqInspectTaskMapper.xml:49-68DqInspectTask.data.ts:174-208superQuerySchema 19 字段)

P2 - 建议

# 维度 问题描述 证据 位置
1 用户体验/共享组件 弹窗关闭 X 与全屏图标紧邻易误触:关闭按钮容器 86×34px 内先渲染 36×36 的全屏图标、再渲染约 26×36 的关闭 glyph,二者仅 12px 间距;BasicModal.handleCancel 又对容器 class-close--custom)点击直接 return 不关闭,于是点在图标间隙/偏左会触发全屏而非关闭。实测点击关闭区中心命中 anticon-fullscreen(弹窗未关),仅点最右侧 26×36 的 glyph 才关闭。该组件为全局共享,所有弹窗都受影响。 实测 artifacts/probe_x_realmouse.jsoncenter 命中 fullscreenafter_real_click_center=1 未关;glyph 26×36 点击后=0 关闭);artifacts/probe_x_glyph.jsonicons=[fullscreen,close]bbox 分别为 36×36、26×36 src/components/Modal/src/components/ModalClose.vue--can-fullmargin-left:12px、glyph padding);src/components/Modal/src/BasicModal.vue:203-215handleCancel 过滤容器 class
2 文案 删除确认文案笼统:单删 popConfirm title 仅「是否确认删除」,批删 createConfirm content「是否删除选中数据」,未说明是否连带删除关联反馈记录/流程,用户无法评估影响。(UX 报告 P2#7 并列) artifacts/delete_popconfirm.txt;截图 61_t8_delete_confirm.png DqInspectTaskList.vue:437DqInspectTask.api.ts:82-93
3 空态 空数据无引导:无「清除筛选/去新建」出口,只有 ant-empty 默认「暂无数据」;在搜索失效场景(P0#1)下尤其误导。(UX 报告 P2#4 并列) artifacts/empty_state_html.html;截图 17_t1b_filter_done.png 列表空态(BasicTable 默认 empty
4 可学习性 发起弹窗「立即发起/重复发起」无解释:两者区别、何时选「重复发起」没有任何说明,业务用户凭感觉选。(UX 报告 P2#5 并列) artifacts/flow_start_modal.txt;截图 50_t3_flow_start_modal.png DqInspectTaskFlowScheduleStartModal.vue:4-9
5 可学习性 高级查询字段名技术化superQuerySchema 多个 title 带「ID」「流程实例ID」等后缀,业务用户无法理解。 artifacts/superquery_modal.txtDqInspectTask.data.ts:175-193 DqInspectTask.data.ts superQuerySchema
6 视觉 状态行底色浅粉彩近白status-row-2 底色 #fff1f0(督办中)、status-row-1 #fffbe6,肉眼几乎看不出,状态辨识价值为零;对色弱用户更不可用。(UX 报告 P2#9,vision+DOM 已复核) artifacts/rowcolors_probe.jsontd 背景 rgb(255,241,240));CSS DqInspectTaskList.vue:643-651;截图 04_list.png DqInspectTaskList.vue:643-651
7 性能/console DeptRoleUserSelectDropDown 未声明 emits 导致控制台 onChange 类型警告:组件没写 emits,父级 @change="reload" 被当作 fallthrough 属性落到根 a-select,与组件内部 onChange 合并成数组 → Invalid prop: type check failed for prop "onChange". Expected Function, got Array,控制台持续刷警告;功能上父级 reload 仍会触发,但属隐患(若将来 antd 校验更严或改传参方式会坏)。 实测 artifacts/eng_15_final.jsonconsole_errors_warnings 含该警告);eng_01_console.json DeptRoleUserSelectDropDown.vue(缺 emits: ['change']);使用处 DqInspectTaskList.vue:14

通过项(做得好的地方)

  • 表单校验体验:空提交一次列出 7 条明确必填提示(DqInspectTaskForm.vue:246-255:请选择具体问题/密级/整改措施/完成时限/措施责任部门/措施责任领导/分管所领导/党群领导审批),且提交失败会 scrollToField 定位到首错字段(353-367 行)。
  • 防误删:单删/批删均有二次确认(popConfirm + createConfirm),批量删除需先勾选行。
  • 状态统计随筛选/操作刷新afterFetch → fetchStatusStats 复用当前 queryParam,实测按 bpmStatus=3 筛选时统计同步归零、按 bpmStatus=2 时统计正常(eng_02_api_bodies.json);操作成功后 handleSuccess → reload 刷新列表与统计。
  • 台账合并单元格实现正确calcLedgerRowSpan当前页内计算问题分类/面上/具体问题的 rowSpan,避免跨页合并导致分页不可控(DqInspectTaskList.vue:353-365)。
  • API 契约整体一致:列表 GET ledgerList、详情 GET queryById、删除 DELETE delete/deleteBatchid 拼 URL)、保存 POST add/edit、状态统计 GET statusStats、发起流程 POST tasktask/taskTask/flow-schedulesRecurringTaskDTO{taskTask,intervalType,startCount})——与后端 Controller 参数绑定一一对应。
  • 流程查看能力完整:「查询督办流程」弹窗含审批历史/流程图/查询当前办理人/修改信息/删除流程入口(实测 eng_06_flow.json query_process_modal)。
  • 详情字段回显:除「措施责任领导」外,具体问题/密级/完成时限/分管所领导等均正确回显(eng_05_detail.json)。
  • 测试数据卫生:本次仅复用既有只读记录做验证;清理了上一轮 eng 残留的 QA_TEST_整改措施_0/_1eng_13_cleanup_uiDELETE id=2087061887133655042),最终列表 1 条原始数据、无 QA_TEST_ 残留(eng_15_final.json)。

测试过程记录

操作步骤与截图

  1. 登录 /user/loginadmin/123456)→ 进列表页(screenshots/eng_15_final_list.png,最终干净态:1 条「wqdwqd/督办中」,统计 未开始0/督办中1/已完成0)。
  2. 整改措施输入 wqdwqd 查询 → 列表 0 行;清空输入 → 仍 0 行(请求带 improveMeasure=**)→ 确认搜索失效(artifacts/eng_10_search_bug.json)。
  3. 分管所领导选「所党委01」→ 列表仍显示全部行(筛选被忽略,artifacts/eng_11_cleanup_filters.json)。
  4. 打开记录详情弹窗 → 「措施责任领导」占位符、value 为空;下拉查询返回 dd_ld_02 但未选中(artifacts/eng_09_leader_rootcause.json,截图 eng_09_detail_modal.png)。
  5. 督办中记录「流程操作」下拉 → 三项全显示,发起整改/销号弹窗均可打开(artifacts/eng_06_flow.json;未点提交)。
  6. 复用 UX 轮证据:关闭按钮 X 误触(probe_x_realmouse.json/probe_x_glyph.json)、删除确认(delete_popconfirm.txt)、空态(empty_state_html.html)。
  7. 清理残留 QA_TEST_整改措施_1scripts/eng_13_cleanup_ui.pyDELETE 成功,QA_TEST 计数归 0)。

console 报错/警告列表(artifacts/eng_15_final.json

  • error: Failed to load resource: net::ERR_CONNECTION_CLOSED(单个资源,多为 iconify/后台请求,影响小)
  • warning: [Vue warn] Failed to resolve component: AppSearch/Notify/AppLocalePicker/SettingDrawer/Aide(全局布局头部组件解析警告,与本页无关,框架级噪音)
  • warning: [Vue warn] Invalid prop: type check failed for prop "onChange". Expected Function, got Array at <DeptRoleUserSelectDropDown>本页相关,P2#7

关键网络请求(方法/URL/状态码)

  • POST /sys/login → 200mock
  • GET /dqinspecttask/dqInspectTask/ledgerList?column=createTime&order=desc&pageNo=1&pageSize=12[&improveMeasure=*wqdwqd*] → 200(搜索参数下 records:[]
  • GET /dqinspecttask/dqInspectTask/statusStats[?improveMeasure=*wqdwqd*] → 200(同参数 inProgress:1,与列表不一致)
  • GET /dqinspecttask/dqInspectTask/queryById?id=2085316903091015681 → 200measureResLeader=dd_ld_02
  • GET /sys/user/queryUserRoleComponentData?departId=2044677731423850498&roleId=2044680793306591234... → 200(返回 dd_ld_02/dd_ld_01,共 2 条)
  • GET /tasktask/taskTask/queryByBusinessId?businessId=... → 200(流程列表)
  • DELETE /dqinspecttask/dqInspectTask/delete?id=2087061887133655042 → 200(清理 QA_TEST

待实测 / 未覆盖(明确标注,不进 P0/P1 判定)

项目 状态 说明
发起流程「提交」是否真创建重复流程实例 代码确认 + 实测入口,未实测提交 前端菜单无条件显示 + 后端 singleFlowStart 无业务守卫(TaskTaskServiceImpl.java:55-75,133-152);为保护真实流程数据未点提交,重复实例风险为代码路径推断,建议后端侧加状态/幂等校验
删除是否级联删除关联反馈/流程记录 代码推断,待实测 仅确认有二次确认弹窗;未点「确定」,后端删除行为需工程师侧补测
高级查询非 6 字段(targetNode 等)对列表失效 代码推断 XML queryLedgerPage 仅 6 个 <if> 子句,与 chargeLeader(已实测忽略)同机制
加载态/后端错误态(断网/500/超时) 未实测 依赖 BasicTable 默认 loading/empty,未发现自定义错误兜底
权限按钮显隐(非 admin 角色) 未覆盖 仅 admin 账号;按钮均有 v-auth 指令(dqinspecttask:dq_inspect_task:add/exportXls/importExcel/deleteBatch),但无法对比验证不同角色显隐
特殊字符/超长文本/快速连点/双标签页并发 未实测 边界输入本轮未覆盖
不同分辨率/小屏适配 未实测 默认 1440 视口

报告按工程师视角分级(P0/P1/P2),证据均来自浏览器实测(截图/网络响应/模态/DOM)或 file:line 代码定位;代码推断项已明确标注"代码推断,待实测",未计入 P0/P1。与 QA_REPORT_UX.md 重叠问题并列呈现,并补充技术根因与修复建议。测试未创建任何新业务数据,清理了上一轮 QA_TEST_ 残留,无残留入库。