fix: 优化excel综合导出水质测站错误问题

This commit is contained in:
tangwei 2026-08-05 16:16:30 +08:00
parent f96d86b1c1
commit 356c4f89ca
3 changed files with 56 additions and 28 deletions

View File

@ -24,10 +24,9 @@ public interface ExportIndicatorProcessor {
* 测站类型STTP用于区分同一电站下不同用途的测站
* <ul>
* <li>V/Q/Z 河道水情 "ZQ"</li>
* <li>WQ 水质 null不区分类型取第一个测站</li>
* <li>WQ 水质 "WQ"</li>
* <li>QEC 生态流量 待定</li>
* </ul>
* 返回 null 表示不按 STTP 过滤取该电站的第一个测站
*/
default String getSttpType() {
return null;

View File

@ -27,7 +27,7 @@ public abstract class WqIndicatorProcessor implements ExportIndicatorProcessor {
@Override
public String getSttpType() {
return null; // 水质不按STTP过滤取第一个测站
return "WQ";
}
@Override

View File

@ -103,7 +103,6 @@ public class QgcExportServiceImpl implements IQgcExportService {
// 2. 收集所有需要的 STTP 类型
Set<String> sttpTypes = processors.stream()
.map(ExportIndicatorProcessor::getSttpType)
.filter(Objects::nonNull)
.collect(Collectors.toCollection(LinkedHashSet::new));
// 3. 电站 测站映射
@ -113,11 +112,8 @@ public class QgcExportServiceImpl implements IQgcExportService {
return;
}
// 4. 电站顺序 + 列标题测站名称
// 4. 电站顺序
List<String> stationOrder = new ArrayList<>(stationRes.displayNames.keySet());
List<String> headerNames = stationOrder.stream()
.map(stationRes::getDisplayName)
.toList();
// 5. 每月一个 ExcelData
List<ExportZipUtil.ExcelData> excelList = new ArrayList<>();
@ -129,9 +125,13 @@ public class QgcExportServiceImpl implements IQgcExportService {
for (ExportIndicatorProcessor processor : processors) {
List<List<Object>> rows = buildSheetRows(processor, mr, stationOrder, stationRes);
if (rows != null) {
// 按当前处理器 STTP 类型获取对应的测站名称
String sttp = processor.getSttpType();
List<String> headers = new ArrayList<>();
headers.add("日期");
headers.addAll(headerNames);
for (String rstcd : stationOrder) {
headers.add(stationRes.getDisplayName(rstcd, sttp));
}
sheets.add(new ExportZipUtil.SheetData(processor.getSheetName(), headers, rows));
}
}
@ -303,26 +303,39 @@ public class QgcExportServiceImpl implements IQgcExportService {
continue;
}
// 测站名称优先 ZQ 类型 STNM 任意 STNM ENNM RSTCD
String displayName = null;
for (StationMapping m : rows) {
if ("ZQ".equals(m.getSttp()) && m.getStnm() != null) {
displayName = m.getStnm();
break;
}
}
if (displayName == null) {
// 默认测站名称按请求的 STTP 类型优先级 任意 STNM ENNM RSTCD
String defaultDisplayName = null;
for (String sttp : sttpTypes) {
for (StationMapping m : rows) {
if (m.getStnm() != null) { displayName = m.getStnm(); break; }
if (sttp.equals(m.getSttp()) && m.getStnm() != null) {
defaultDisplayName = m.getStnm();
break;
}
}
if (defaultDisplayName != null) break;
}
if (defaultDisplayName == null) {
for (StationMapping m : rows) {
if (m.getStnm() != null) { defaultDisplayName = m.getStnm(); break; }
}
}
if (displayName == null) {
displayName = rows.get(0).getEnnm();
if (defaultDisplayName == null) {
defaultDisplayName = rows.get(0).getEnnm();
}
if (displayName == null) {
displayName = rstcd;
if (defaultDisplayName == null) {
defaultDisplayName = rstcd;
}
result.displayNames.put(rstcd, displayName);
result.displayNames.put(rstcd, defaultDisplayName);
// STTP 类型分别记录测站名称水质 Sheet WQ 名称水情 Sheet ZQ 名称
Map<String, String> sttpNames = new LinkedHashMap<>();
for (StationMapping m : rows) {
String sttp = m.getSttp();
if (sttp != null && m.getStnm() != null && !sttpNames.containsKey(sttp)) {
sttpNames.put(sttp, m.getStnm());
}
}
result.sttpDisplayNames.put(rstcd, sttpNames);
// STTP STCD 映射
Map<String, String> sttpMap = new LinkedHashMap<>();
@ -460,22 +473,38 @@ public class QgcExportServiceImpl implements IQgcExportService {
// ======================== 内部数据类 ========================
private static class StationResolution {
/** 默认测站名称fallbackRSTCD → displayName */
final Map<String, String> displayNames = new LinkedHashMap<>();
/** 按 STTP 分组的测站名称RSTCD → {STTP → displayName} */
final Map<String, Map<String, String>> sttpDisplayNames = new LinkedHashMap<>();
/** STTP → STCD 映射RSTCD → {STTP → STCD} */
final Map<String, Map<String, String>> sttpStcdMap = new LinkedHashMap<>();
/** 获取默认测站名称 */
String getDisplayName(String rstcd) {
return displayNames.getOrDefault(rstcd, rstcd);
}
/**
* 获取指定 STTP 的测站编码sttp null 时返回第一个可用的 STCD
* 获取指定 STTP 类型的测站名称
* 优先返回该 STTP 对应的名称若无则返回默认名称
*/
String getDisplayName(String rstcd, String sttp) {
Map<String, String> inner = sttpDisplayNames.get(rstcd);
if (inner != null) {
String name = inner.get(sttp);
if (name != null) return name;
}
return getDisplayName(rstcd);
}
/**
* 获取指定 STTP 的测站编码
*/
String getStcd(String rstcd, String sttp) {
Map<String, String> inner = sttpStcdMap.get(rstcd);
if (inner == null || inner.isEmpty()) return null;
if (sttp != null) return inner.get(sttp);
// sttp null返回第一个可用的 STCD
return inner.values().iterator().next();
return inner.get(sttp);
}
}