① 基本信息
| 问题描述 | 新型储能的计划并网审核通过之后,能量MWh的数值丢失,没有在页面展示出来 |
|---|---|
| 一级模块 | 计划并网信息 |
| 二级模块 | / |
| 涉及类型 | 新型储能 |
| 所属区域 | 不确定或共性 |
| 严重性 | 严重 |
| 当前状态 | 2.1.待开发 |
| 研发处理人 | 陈文琛 |
| 处理说明 | 待调整 |
② 问题截图
③ 旧代码涉及的项目文件及行数
xnybw5f / src/views/projectNew/components/planInfo/jhbwDetail.vue
第 1900-1915 行:showPracticalCapa / getPracticalCapa(决定某年某月是否切换为"已并网实际值"只读展示,以及取值来源)
showPracticalCapa(index, year, month) {
let yearMonth = year + "年" + month + "月"
return (this.practicalYearMonthList[index] && this.practicalYearMonthList[index].includes(yearMonth))
},
getPracticalCapa(index, year, filed) {
let capa = null
let practicalDetailList = this.projectImp.implList[index].practicalDetailList
let data = practicalDetailList.find(item => item.year == year)
if (data) { capa = data[filed] } // filed 传入 'capacityXxxMwh' 时,若 practicalDetailList 中该字段本就没有值,这里直接返回 undefined/null
return capa
}
xnybw5b / src/main/java/cn/csg/so/oms/in/newenergy/project/appservice/JhbwAppService.java
第 1826-1883 行 findPracticalCapa(计算 practicalDetailList 的来源方法,第 139-142 行被调用处)
public List<NePjImplDetailVO> findPracticalCapa(String implId, String type) {
...
if (ProjectTypeConstant.isEnergy(type)) { // 新型储能分支:确实同时计算了 容量(rl) 和 能量(nl)
List<NePwrEnVO> list = powerEnergyService.getListByImplId(implId);
for (NePwrEnVO energy : list) {
...
BigDecimal rl = ObjectUtil.isNotEmpty(energy.getGdyedgl()) ? new BigDecimal(energy.getGdyedgl()) : BigDecimal.ZERO;
BigDecimal nl = ObjectUtil.isNotEmpty(energy.getGdyedglnl()) ? new BigDecimal(energy.getGdyedglnl()) : BigDecimal.ZERO; // 能量字段为空时静默按0处理,不报错也不告警
...
String filedMwh = filed + "Mwh";
detailMap.put(filedMwh, nl.add(new BigDecimal(oldNl)).toString());
}
} else { // 非储能分支(集中式/生物质等):只计算了容量,完全没有 filedMwh 这一项
List<NePwrPlVO> list = powerPlantService.getListByImplId(implId);
for (NePwrPlVO entity : list) {
...
detailMap.put(filed, rl.add(new BigDecimal(oldRl)).toString());
// 没有 detailMap.put(filedMwh, ...)
}
}
return BeanUtil.copyToList(newDetailMap.values(), NePjImplDetailVO.class);
}
定位结论:
findPracticalCapa 对"新型储能"类型(isEnergy(type) 分支)本身逻辑是完整的,会同时计算容量和能量两个字段并放入 practicalDetailList;能量数值的唯一来源是 NePwrEnVO.getGdyedglnl()(实际并网信息里录入的"额定能量"字段)。若该字段在"实际并网容量信息"录入环节被留空(非强制必填,或历史数据缺失),这里会静默按 BigDecimal.ZERO 处理并汇总,前端 getPracticalCapa 因此拿到的是 0 或空,页面呈现为"数值丢失"。这与截图中"MW 有值、MWh 无值"的现象吻合——容量字段的对应源字段一般是必填项,能量字段则可能未被同等强制校验。
④ 修复代码涉及的项目文件及行数
xnybw5b / src/main/java/cn/csg/so/oms/in/newenergy/project/appservice/JhbwAppService.java
第 1842 行附近:findPracticalCapa 中 energy.getGdyedglnl() 取值前增加数据缺失识别
BigDecimal rl = ObjectUtil.isNotEmpty(energy.getGdyedgl()) ? new BigDecimal(energy.getGdyedgl()) : BigDecimal.ZERO; -BigDecimal nl = ObjectUtil.isNotEmpty(energy.getGdyedglnl()) ? new BigDecimal(energy.getGdyedglnl()) : BigDecimal.ZERO; +if (ObjectUtil.isEmpty(energy.getGdyedglnl())) { + log.warn("新型储能实际并网能量(MWh)字段为空,implId={}, energyId={},页面将显示为0", implId, energy.getId()); +} +BigDecimal nl = ObjectUtil.isNotEmpty(energy.getGdyedglnl()) ? new BigDecimal(energy.getGdyedglnl()) : BigDecimal.ZERO;
xnybw5f / src/views/projectNew/components/actualInfo(实际并网容量信息录入表单,新型储能"额定能量"字段)
建议将"额定能量(MWh)"字段改为必填(与"额定容量"字段同等校验级别),从源头保证 NePwrEnVO.gdyedglnl 不为空
⑤ 修复方案
本条问题的根因不是"计算逻辑写错了",而是数据来源可能为空、且为空时被静默按0处理,前后端都没有对"缺失"和"确实为0"做区分:
- 后端:在
JhbwAppService.findPracticalCapa中为空的gdyedglnl增加日志告警,便于后续排查是哪些历史场站/机组缺失了能量数据; - 源头治理:核实"实际并网容量信息"录入表单中新型储能场景下"额定能量(MWh)"字段是否为必填项,如果不是,建议提升为必填,避免用户只填容量不填能量;
- 前端展示优化:
jhbwDetail.vue中getPracticalCapa返回null/undefined时,页面当前直接渲染空白,容易被误解为"系统丢数据";建议区分"确实是0"与"字段缺失"两种情况,缺失时给出更明确的提示(如显示"-"或悬浮提示"该机组未填报实际并网能量"),减少用户对"数据丢失"的误判。
该问题涉及历史数据补录范围,建议同时核查已审核通过的历史项目中有多少条记录
gdyedglnl 为空,评估是否需要批量数据补录。