fix: 增加excel综合导出坝上、坝下水位数据

This commit is contained in:
tangwei 2026-08-05 17:12:47 +08:00
parent 9d45d85fc6
commit c17bf6fd08
13 changed files with 480 additions and 3 deletions

View File

@ -0,0 +1,89 @@
package com.yfd.platform.qgc_export.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 电站运行数据表小时级
* 对应 Oracle : QGC_REFA.SD_HYDROPW_R
*/
@Data
@TableName("SD_HYDROPW_R")
public class SdHydropwR implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.INPUT)
private String id;
/** 水电工程编码 */
private String stcd;
/** 数据时间 */
private Date tm;
/** 坝上水位 (m) */
private BigDecimal rz;
/** 蓄水量 */
private BigDecimal w;
/** 坝下水位 (m) */
private BigDecimal dz;
/** 入库流量 */
private BigDecimal qi;
/** 出库流量 */
private BigDecimal qo;
/** 发电流量 */
private BigDecimal qn;
/** 泄洪流量 */
private BigDecimal qgt;
/** 生态流量 */
private BigDecimal qec;
/** 灌溉流量 */
private BigDecimal qc;
/** 发电量 */
private BigDecimal ge;
/** 平均出力 */
private BigDecimal na;
/** 生态流量是否达标 */
private Integer sfdb;
/** 泄洪水量 */
private BigDecimal gtw;
/** 发电水量 */
private BigDecimal wge;
/** 区间流量 */
private BigDecimal qr;
/** 耗水率 */
private BigDecimal wr;
/** 记录人等... */
private String recordUser;
private Date recordTime;
private String modifyUser;
private Date modifyTime;
private Integer isDeleted;
private String deleteUser;
private Date deleteTime;
private String fid;
private String remark;
}

View File

@ -0,0 +1,72 @@
package com.yfd.platform.qgc_export.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 电站运行数据日统计表
* 对应 Oracle : QGC_REFA.SD_HYDROPWDAY_S
*/
@Data
@TableName("SD_HYDROPWDAY_S")
public class SdHydropwdayS implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.INPUT)
private String id;
/** 水电工程编码 */
private String stcd;
/** 时间 */
private Date dt;
/** 坝上水位 (m) */
private BigDecimal rz;
/** 蓄水量 */
private BigDecimal w;
/** 坝下水位 (m) */
private BigDecimal dz;
/** 入库流量 */
private BigDecimal qi;
/** 出库流量 */
private BigDecimal qo;
/** 发电流量 */
private BigDecimal qn;
/** 泄洪流量 */
private BigDecimal qgt;
/** 生态流量 */
private BigDecimal qec;
/** 灌溉流量 */
private BigDecimal qc;
/** 发电量 */
private BigDecimal ge;
/** 平均出力 */
private BigDecimal na;
/** 记录人等... */
private String recordUser;
private Date recordTime;
private String modifyUser;
private Date modifyTime;
private Integer isDeleted;
private String deleteUser;
private Date deleteTime;
}

View File

@ -0,0 +1,28 @@
package com.yfd.platform.qgc_export.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.qgc_export.domain.SdHydropwR;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* SD_HYDROPW_R 电站运行小时数据 Mapper
*/
public interface SdHydropwRMapper extends BaseMapper<SdHydropwR> {
/**
* 批量查询测站在指定时间范围内的原始小时数据动态字段
*
* @param stcdList 测站编码列表
* @param fieldName 查询字段名RZ/DZ
* @param startTime 起始时间
* @param endTime 结束时间
* @return [STCD, TM, VALUE]
*/
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
@Param("fieldName") String fieldName,
@Param("startTime") String startTime,
@Param("endTime") String endTime);
}

View File

@ -0,0 +1,28 @@
package com.yfd.platform.qgc_export.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.qgc_export.domain.SdHydropwdayS;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* SD_HYDROPWDAY_S 电站运行日数据 Mapper
*/
public interface SdHydropwdaySMapper extends BaseMapper<SdHydropwdayS> {
/**
* 批量查询测站在指定时间范围内的原始日数据动态字段
*
* @param stcdList 测站编码列表
* @param fieldName 查询字段名RZ/DZ
* @param startTime 起始时间
* @param endTime 结束时间
* @return [STCD, DT, VALUE]
*/
List<Map<String, Object>> selectRawData(@Param("stcdList") List<String> stcdList,
@Param("fieldName") String fieldName,
@Param("startTime") String startTime,
@Param("endTime") String endTime);
}

View File

@ -0,0 +1,20 @@
package com.yfd.platform.qgc_export.processor;
import org.springframework.stereotype.Component;
/**
* 坝下水位(DZ) 标准格式处理器
*/
@Component
public class DzProcessor extends HydropwIndicatorProcessor {
@Override
public String getFieldName() {
return "DZ";
}
@Override
public String getSheetName() {
return "坝下水位";
}
}

View File

@ -0,0 +1,25 @@
package com.yfd.platform.qgc_export.processor;
import org.springframework.stereotype.Component;
/**
* 坝下水位(DZ) 日变幅格式处理器
*/
@Component
public class DzVariationProcessor extends HydropwIndicatorProcessor {
@Override
public String getFieldName() {
return "DZ";
}
@Override
public String getSheetName() {
return "坝下水位日变幅";
}
@Override
public boolean isVariation() {
return true;
}
}

View File

@ -26,6 +26,7 @@ public interface ExportIndicatorProcessor {
* <li>V/Q/Z 河道水情 "ZQ"</li> * <li>V/Q/Z 河道水情 "ZQ"</li>
* <li>WQ 水质 "WQ"</li> * <li>WQ 水质 "WQ"</li>
* <li>DWT 出库水温 "WTRV"</li> * <li>DWT 出库水温 "WTRV"</li>
* <li>RZ/DZ 坝上/坝下水位 "ENG"</li>
* <li>QEC 生态流量 待定</li> * <li>QEC 生态流量 待定</li>
* </ul> * </ul>
*/ */

View File

@ -0,0 +1,69 @@
package com.yfd.platform.qgc_export.processor;
import com.yfd.platform.qgc_export.mapper.SdHydropwRMapper;
import com.yfd.platform.qgc_export.mapper.SdHydropwdaySMapper;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 电站运行指标处理器基类 RZ(坝上水位)/DZ(坝下水位) 使用 SD_HYDROPW_R / SD_HYDROPWDAY_S
* <p>
* 子类标注 @ComponentgetSttpType() 固定返回 "ENG"
* 动态字段名由子类 getFieldName() 返回
*/
public abstract class HydropwIndicatorProcessor implements ExportIndicatorProcessor {
protected SdHydropwRMapper sdHydropwRMapper;
protected SdHydropwdaySMapper sdHydropwdaySMapper;
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void setMappers(SdHydropwRMapper rMapper, SdHydropwdaySMapper sMapper) {
this.sdHydropwRMapper = rMapper;
this.sdHydropwdaySMapper = sMapper;
}
@Override
public String getSttpType() {
return "ENG";
}
@Override
public int getDecimalPlaces() {
return 3;
}
@Override
public List<IndicatorDataRow> queryRawData(List<String> stcds, Date startTime, Date endTime, boolean isDaily) {
String startStr = SDF.format(startTime);
String endStr = SDF.format(endTime);
List<Map<String, Object>> rawList;
if (isDaily) {
rawList = sdHydropwdaySMapper.selectRawData(stcds, getFieldName(), startStr, endStr);
} else {
rawList = sdHydropwRMapper.selectRawData(stcds, getFieldName(), startStr, endStr);
}
List<IndicatorDataRow> rows = new ArrayList<>();
if (rawList != null) {
for (Map<String, Object> map : rawList) {
String stcd = (String) map.get("STCD");
Date tm = (Date) map.get(isDaily ? "DT" : "TM");
BigDecimal value = toBigDecimal(map.get("VALUE"));
if (stcd != null && tm != null && value != null) {
rows.add(new IndicatorDataRow(stcd, tm, value));
}
}
}
return rows;
}
private BigDecimal toBigDecimal(Object val) {
if (val instanceof BigDecimal) return (BigDecimal) val;
if (val instanceof Number) return BigDecimal.valueOf(((Number) val).doubleValue());
return null;
}
}

View File

@ -0,0 +1,20 @@
package com.yfd.platform.qgc_export.processor;
import org.springframework.stereotype.Component;
/**
* 坝上水位(RZ) 标准格式处理器
*/
@Component
public class RzProcessor extends HydropwIndicatorProcessor {
@Override
public String getFieldName() {
return "RZ";
}
@Override
public String getSheetName() {
return "坝上水位";
}
}

View File

@ -0,0 +1,25 @@
package com.yfd.platform.qgc_export.processor;
import org.springframework.stereotype.Component;
/**
* 坝上水位(RZ) 日变幅格式处理器
*/
@Component
public class RzVariationProcessor extends HydropwIndicatorProcessor {
@Override
public String getFieldName() {
return "RZ";
}
@Override
public String getSheetName() {
return "坝上水位日变幅";
}
@Override
public boolean isVariation() {
return true;
}
}

View File

@ -7,6 +7,8 @@ import com.yfd.platform.qgc_export.mapper.SdWqRMapper;
import com.yfd.platform.qgc_export.mapper.SdWqdaySMapper; import com.yfd.platform.qgc_export.mapper.SdWqdaySMapper;
import com.yfd.platform.qgc_export.mapper.SdWtrvRMapper; import com.yfd.platform.qgc_export.mapper.SdWtrvRMapper;
import com.yfd.platform.qgc_export.mapper.SdWtrvdaySMapper; import com.yfd.platform.qgc_export.mapper.SdWtrvdaySMapper;
import com.yfd.platform.qgc_export.mapper.SdHydropwRMapper;
import com.yfd.platform.qgc_export.mapper.SdHydropwdaySMapper;
import com.yfd.platform.qgc_export.mapper.StationMappingMapper; import com.yfd.platform.qgc_export.mapper.StationMappingMapper;
import com.yfd.platform.qgc_export.processor.*; import com.yfd.platform.qgc_export.processor.*;
import com.yfd.platform.qgc_export.service.IQgcExportService; import com.yfd.platform.qgc_export.service.IQgcExportService;
@ -29,7 +31,16 @@ import java.util.stream.Collectors;
* 综合导出服务实现月度报表 * 综合导出服务实现月度报表
* <p> * <p>
* 格式每月一个 Excel 文件 ZIP 下载 * 格式每月一个 Excel 文件 ZIP 下载
* 每个 Excel 含多个 Sheet顺序水温PH溶解氧电导率浊度流速流量水位 * 每个 Excel 含多个 Sheet顺序由前端 dataField 参数决定
*
* <h3>支持的指标</h3>
* <ul>
* <li>WQ: wtmp/ph/dox/cond/tu STTP=WQ, 8个汇总指标(含小时达标率)</li>
* <li>河道水情: v/q/z STTP=ZQ, 7个汇总指标</li>
* <li>出库水温: dwt STTP=WTRV, 2个Sheet(标准+日变幅)</li>
* <li>坝上水位: rz STTP=ENG, 2个Sheet(标准+日变幅)</li>
* <li>坝下水位: dz STTP=ENG, 2个Sheet(标准+日变幅)</li>
* </ul>
* *
* <h3>Sheet 结构</h3> * <h3>Sheet 结构</h3>
* <pre> * <pre>
@ -93,6 +104,20 @@ public class QgcExportServiceImpl implements IQgcExportService {
@Resource @Resource
private DwtVariationProcessor dwtVariationProcessor; private DwtVariationProcessor dwtVariationProcessor;
// RZ/DZ 坝上/坝下水位相关STTP=ENG
@Resource
private SdHydropwRMapper sdHydropwRMapper;
@Resource
private SdHydropwdaySMapper sdHydropwdaySMapper;
@Resource
private RzProcessor rzProcessor;
@Resource
private RzVariationProcessor rzVariationProcessor;
@Resource
private DzProcessor dzProcessor;
@Resource
private DzVariationProcessor dzVariationProcessor;
private static final SimpleDateFormat SDF_TIME = new SimpleDateFormat("dd日 HH时"); private static final SimpleDateFormat SDF_TIME = new SimpleDateFormat("dd日 HH时");
/** 基础汇总指标7个 */ /** 基础汇总指标7个 */
@ -293,6 +318,22 @@ public class QgcExportServiceImpl implements IQgcExportService {
result.add(dwtVariationProcessor); result.add(dwtVariationProcessor);
continue; continue;
} }
// RZ 坝上水位 展开为标准格式 + 日变幅两个 Sheet
if ("rz".equals(field)) {
rzProcessor.setMappers(sdHydropwRMapper, sdHydropwdaySMapper);
rzVariationProcessor.setMappers(sdHydropwRMapper, sdHydropwdaySMapper);
result.add(rzProcessor);
result.add(rzVariationProcessor);
continue;
}
// DZ 坝下水位 展开为标准格式 + 日变幅两个 Sheet
if ("dz".equals(field)) {
dzProcessor.setMappers(sdHydropwRMapper, sdHydropwdaySMapper);
dzVariationProcessor.setMappers(sdHydropwRMapper, sdHydropwdaySMapper);
result.add(dzProcessor);
result.add(dzVariationProcessor);
continue;
}
ExportIndicatorProcessor p = processorMap.get(field); ExportIndicatorProcessor p = processorMap.get(field);
if (p != null) { if (p != null) {
@ -314,11 +355,24 @@ public class QgcExportServiceImpl implements IQgcExportService {
if (rstcds == null || rstcds.isEmpty()) return result; if (rstcds == null || rstcds.isEmpty()) return result;
List<StationMapping> mappings = stationMappingMapper.selectList( List<StationMapping> mappings = stationMappingMapper.selectList(
new LambdaQueryWrapper<StationMapping>().in(StationMapping::getRstcd, rstcds)); new LambdaQueryWrapper<StationMapping>()
.in(StationMapping::getRstcd, rstcds)
.or()
.in(StationMapping::getStcd, rstcds)
);
// 添加逻辑如果 sttp "ENG" rstcd 赋值为 stcd
mappings.forEach(mapping -> {
if ("ENG".equals(mapping.getSttp())) {
mapping.setRstcd(mapping.getStcd());
}
});
Map<String, List<StationMapping>> byRstcd = new LinkedHashMap<>(); Map<String, List<StationMapping>> byRstcd = new LinkedHashMap<>();
for (StationMapping m : mappings) { for (StationMapping m : mappings) {
if (m.getRstcd() == null) continue; if (!"ENG".equals(m.getSttp()) && m.getRstcd() == null) {
continue;
}
byRstcd.computeIfAbsent(m.getRstcd(), k -> new ArrayList<>()).add(m); byRstcd.computeIfAbsent(m.getRstcd(), k -> new ArrayList<>()).add(m);
} }

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdHydropwRMapper">
<!-- 电站运行小时数据动态字段查询 -->
<select id="selectRawData" resultType="java.util.HashMap">
SELECT
STCD,
TM,
${fieldName} AS VALUE
FROM SD_HYDROPW_R
WHERE IS_DELETED = 0
AND STCD IN
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
#{stcd}
</foreach>
AND TM &gt;= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TM &lt; TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
AND ${fieldName} IS NOT NULL
</select>
</mapper>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yfd.platform.qgc_export.mapper.SdHydropwdaySMapper">
<!-- 电站运行日数据动态字段查询 -->
<select id="selectRawData" resultType="java.util.HashMap">
SELECT
STCD,
DT,
${fieldName} AS VALUE
FROM SD_HYDROPWDAY_S
WHERE IS_DELETED = 0
AND STCD IN
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
#{stcd}
</foreach>
AND DT &gt;= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND DT &lt; TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
AND ${fieldName} IS NOT NULL
</select>
</mapper>