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

Row 69:生物质类型,预计首次/全部并网时间调整后,计划并网容量表格未自动删除超出区间的年份行

严重 2.1.待开发 生物质 五区(未标注区域,按模块判断属互联网侧) 模块:项目信息填报 / - 处理人:未指派

1基本信息

问题描述生物质类型,预计首次并网时间、预计全部并网时间修改后,不在时间区间内的年份,保存后,下面的表格没有自动删除年份。
所属模块项目信息填报 / -
严重程度严重
涉及类型生物质
提出人文日明
处理人 / 状态未指派 / 2.1.待开发

2问题截图

计划并网容量信息-预计首次并网时间与年度表格
图1:"测试1111444"项目,"预计首次并网时间=2026-08-01、预计全部并网时间=2026-09-17"(红框),按此区间应只覆盖2026年,但下方表格仍保留"2027"整年一行空数据(红框)

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

年度行的生成逻辑在后端 —— xnybw5b@730backup:src/main/java/cn/csg/so/oms/in/newenergy/project/appservice/JhbwAppService.java 第 772-802 行 findDetailMap(List<NePjImplVO> implList)

public Map<String, List<NePjImplDetailVO>> findDetailMap(List<NePjImplVO> implList) {
    for (NePjImplVO impl : implList) {
        List<NePjImplDetailVO> detailList = new ArrayList<>();
        String bakPstatus = impl.getBakPstatus();
        String implId = impl.getId();
        String type = impl.getType();
        if (StrUtil.equals(bakPstatus, "0") || ProjectTypeConstant.isZYFBSXNY(type) || ProjectTypeConstant.isSWZ(type)) {  // 第780行:生物质(isSWZ)命中此分支
            List<NePjImplDetAdjVO> adjustList = NePjImplDetAdjAppService.listByImplId(impl.getId());
            if (CollectionUtil.isNotEmpty(adjustList)) {
                detailList = BeanUtil.copyToList(adjustList, NePjImplDetailVO.class);
            } else {
                detailList = NePjImplDetailAppService.listByImplId(impl.getId());   // 第785行:查出该场站【历史上所有已保存过】的年度行,不带年份范围过滤
            }
            List<String> batchYearMonthList = impl.getBatchYearMonthList();          // 由当前 predictFirstTime~predictAllTime 计算得出的最新年月列表
            for (String yearMonth : batchYearMonthList) {
                String year = yearMonth.substring(0, 4);
                List<NePjImplDetailVO> filterDetailList = detailList.stream()
                        .filter(detail -> StrUtil.equals(detail.getYear(), year)).collect(Collectors.toList());
                if (CollectionUtil.isEmpty(filterDetailList)) {
                    NePjImplDetailVO detail = new NePjImplDetailVO();                // 第793-796行:区间内缺失的年份【会被补一行】
                    detail.setImplId(implId);
                    detail.setYear(year);
                    detailList.add(detail);
                }
            }
            // 第799行方法体结束前:detailList 仍然保留着第785行查出来的全部历史年份,
            // 整个循环只有"新增缺失年份"这一种操作,没有任何一行代码把区间之外的旧年份从 detailList 中剔除
        }
        detailMap.put(implId, detailList);
    }
    return detailMap;
}
根因说明:
只增不删:第 785 行 NePjImplDetailAppService.listByImplId(impl.getId()) 查询的是该场站历史上所有已持久化保存过的年度行(例如用户曾经先把预计全部并网时间设为 2027 年并保存过一次,2027 年的空行就已经落库),第 786-797 行的循环只负责"当前 batchYearMonthList 覆盖的年份里,如果 detailList 还没有对应行,就新建一行补上",但从未对 detailList 做反向过滤——即从未剔除"存在于 detailList,但已经不在最新 batchYearMonthList 覆盖范围内"的年份行。因此当用户把预计全部并网时间从 2027 年调小到 2026 年并保存后,2027 年这一行仍会随着旧的持久化数据被查出来、原样返回给前端展示。
与调用链吻合:该方法被 findImplDetail()(第 1898-1910 行,前端"计划并网容量信息"页面加载详情时调用)与列表批量查询等多处复用,属于查询展示的公共方法,因此这一"只增不删"的缺陷会影响所有走此方法的类型(生物质 isSWZ、中压分布式 isZYFBSXNY、以及 bakPstatus=="0" 的其他场站),不只是截图所反映的生物质类型。

4修复方案

修复代码文件:JhbwAppService.java 第 772-802 行 findDetailMap,在"新增缺失年份"的循环结束之后(原第 797 行 } 循环体结束、第 799 行 detailMap.put(implId, detailList) 之前),补上按 batchYearMonthList 年份集合过滤 detailList 的步骤:

List<String> batchYearMonthList = impl.getBatchYearMonthList();
<ins>
// 新增:当前预计首次/全部并网时间区间覆盖到的年份集合
java.util.Set<String> validYearSet = batchYearMonthList.stream()
        .map(ym -> ym.substring(0, 4))
        .collect(java.util.stream.Collectors.toSet());
</ins>
for (String yearMonth : batchYearMonthList) {
    String year = yearMonth.substring(0, 4);
    List<NePjImplDetailVO> filterDetailList = detailList.stream()
            .filter(detail -> StrUtil.equals(detail.getYear(), year)).collect(Collectors.toList());
    if (CollectionUtil.isEmpty(filterDetailList)) {
        NePjImplDetailVO detail = new NePjImplDetailVO();
        detail.setImplId(implId);
        detail.setYear(year);
        detailList.add(detail);
    }
}
<ins>
// 新增:剔除不再落在预计首次~全部并网时间区间内的历史年份行,避免调小时间区间后旧年份行仍然展示
detailList = detailList.stream()
        .filter(detail -> validYearSet.contains(detail.getYear()))
        .collect(java.util.stream.Collectors.toList());
</ins>

该过滤只影响本次查询返回给前端的展示数据,不会物理删除数据库中已持久化的年度行记录(如后续用户把时间区间调回覆盖该年份,历史容量数据仍可恢复展示);若产品侧确认"调小区间后旧年份数据应彻底作废/清空",可在保存接口(JhbwAppService.java 中处理"保存并提交审核"的方法)中额外增加对 NePjImplDetailAppService 持久化表的物理清理逻辑,本次因不确定该清理是否会影响审计追溯,未直接采用物理删除方案。

效果:预计首次/全部并网时间调整并保存后,"计划并网容量信息"表格只展示当前时间区间覆盖到的年份行,超出区间的历史年份行(如截图中的2027年空行)不再显示,与"下面的表格自动删除年份"的预期一致;该修复同时惠及生物质、中压分布式等所有复用 findDetailMap 的类型。