生成时间: 2026-08-03 · 数据来源: xnybw平台需求及工作计划.xlsx(南网在线绿能云缺陷跟踪表)· 仅针对 backup730/730backup 分支代码

Row 40:列表实际条数与分页栏统计总数不一致(个别场景总数显示为0)

严重 已关闭 · 复测通过 全部类型 模块:项目信息填报 处理人:周小龙

1基本信息

问题描述列表需要有20条数据,分页栏只展示17条数据;集中式已投产查询出来列表有3条数据,分页栏展示0条。
所属模块项目信息填报
严重程度严重(阻断流程:否)
涉及类型全部类型
提出人刘向诚
处理人 / 状态周小龙 / 5.1.已关闭(复测通过)

2问题截图

共16条但列表更多
图1:分页栏显示"共16条"
已投产筛选0条但实际有数据
图2:"项目状态=已投产"筛选后,分页栏显示"共0条",但表格里能看到第2、3条实际数据行

3旧代码定位(backup730 / 730backup 分支)

前端 total 与 list 同源赋值:xnybw5f · src/views/projectNew/utils/ListDataUtils.js 第 139-156 行:

ListDataUtils.listDataInit = (response) => {
  let elTableData = { list: [], pages:0, current: 0, size: 20, total: 0 }
  if (response.code == 200 || response.code == 0) {
    elTableData.list = response.data.records   // 列表数据
    elTableData.total = response.data.total    // 分页总数——与 list 来自同一个 IPage 响应体
  }
  return elTableData
}

后端 xnybw5b · src/main/java/cn/csg/so/oms/in/newenergy/project/appservice/ProjectImplAppService.java 第 220-320 行 selectAll()list 和 total 分别来自两条独立维护的 SQL

// 总记录数:走独立的 selectOne 查询
total = (Long) getCapBaseCommonDAO().selectOne(
        "cn.csg.so.oms.in.newenergy.project.model.NePjImplVO_selectAllCount", param);

// 分页数据:走独立的分页查询
records = getCapBaseCommonDAO().queryList(
        "cn.csg.so.oms.in.newenergy.project.model.NePjImplVO_selectAll",
        param, param.getPageNum(), param.getPageSize());

IPage<NePjImplVO> queryVoPage = new cn.csg.so.oms.in.newenergy.common.page.Page<>(
        param.getPageNum(), param.getPageSize(), total, records);

xnybw5b · .../dbconfig/NePjImplSQL_mysql.xmlNePjImplVO_selectAll(第161行起)与 NePjImplVO_selectAllCount(第324行起)是两段各约 80 行、独立手写维护的动态 SQL,过滤条件(provinces/municipals/types/typeSql/tj/projectStatus/adjustStatus/keyword…)几乎逐条复制:

-- selectAll 的数据来源子查询(带窗口函数,用于按 plan_name 分组取最新记录排序)
select t.*, max(create_time) over (partition by plan_name) as group_latest
from so_in_ne_pj_impl t where t.p_status in ('3','4','5')

-- selectAllCount 的数据来源子查询(普通过滤,无窗口函数)
select * from SO_IN_NE_PJ_IMPL where p_status IN ('3','4','5')
根因说明:list(记录)与 total(总数)分别由 NePjImplVO_selectAllNePjImplVO_selectAllCount 两条独立维护、各自约80行动态 <if> 条件的 SQL 语句执行得到,而不是用同一条 SQL + 分页插件(如 COUNT(*) OVER() 窗口函数或 MyBatis-Plus 物理分页拦截器)一次性返回。这种"一份过滤逻辑维护两份"的写法,任何一次需求变更(例如本次新增的"项目状态"多选过滤)只要有一处遗漏同步(哪怕是 <if> 条件顺序、参数类型细微差异),就会导致 total 和 list 的行数从两条不同路径计算出不一致的结果——这正是"20条数据分页栏显示17条""已投产3条数据分页栏显示0条"这类问题反复出现的结构性原因。

4修复方案

修复文件:NePjImplSQL_mysql.xml / NePjImplSQL_dm.xml + ProjectImplAppService.java

根本修复(推荐):合并为一条 SQL,用窗口函数一次性同时返回记录与总数,从源头消除"两条 SQL 各自维护过滤条件"的不一致风险:
<select id="NePjImplVO_selectAllWithCount" resultType="cn.csg.so.oms.in.newenergy.project.model.NePjImplVO">
  select t.*, count(*) over() as total_count
  from (
    select t.*, max(create_time) over (partition by plan_name) as group_latest
    from so_in_ne_pj_impl t where t.p_status in ('3','4','5')
  ) t
  where 1=1
  <!-- 原 selectAll 里的全部 <if> 过滤条件保留在此,只维护一份 -->
  ...
  order by group_latest desc, create_time desc
  limit #{offset}, #{pageSize}
</select>
// ProjectImplAppService.java:records 与 total 来自同一次查询,天然一致
List<NePjImplVO> records = getCapBaseCommonDAO().queryList(
        "cn.csg.so.oms.in.newenergy.project.model.NePjImplVO_selectAllWithCount",
        param, param.getPageNum(), param.getPageSize());
long total = records.isEmpty() ? 0L : records.get(0).getTotalCount();
IPage<NePjImplVO> queryVoPage = new cn.csg.so.oms.in.newenergy.common.page.Page<>(
        param.getPageNum(), param.getPageSize(), total, records);
过渡方案(改动更小):短期内不合并 SQL,但建立"两段 <if> 条件必须逐字段同步"的强约束——将公共过滤条件抽成 MyBatis <sql id="commonWhere"> 片段,selectAllselectAllCount 都通过 <include refid="commonWhere"/> 复用同一份条件定义,避免手工复制导致的遗漏:
<sql id="commonWhere">
  <if test="creatorPhone != null and creatorPhone != ''">and creator_phone = #{creatorPhone}</if>
  ... <!-- 全部过滤条件只写一份 -->
</sql>

<select id="NePjImplVO_selectAll" ...>
  select ... from (...) t where 1=1 <include refid="commonWhere"/> order by ...
</select>
<select id="NePjImplVO_selectAllCount" ...>
  select count(*) from (...) t where 1=1 <include refid="commonWhere"/>
</select>
效果:无论采用哪种方案,list 与 total 都不再依赖"两份手写 SQL 保持同步"这一脆弱前提,从根本上消除分页栏总数与列表实际条数不一致的问题。