Преглед изворни кода

[10023] 气压曲线页面优化: psfcchart接口改为返回forecast/local时间点并集(时间升序, 缺数填0, 两侧stats等长下标对齐, 预测源同时间点多份重叠报告取首个即最新); 明细表与导出Excel均改为 时间/预测气压(hPa)/观测气压(hPa) 3列, 导出新增PsfcChartExportStat VO

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
taosj пре 6 дана
родитељ
комит
4c0cc8a95c

+ 56 - 8
forecast-backend-server/src/main/java/com/ufo/project/forecast/shortterm/weather/controller/DataShortTermWeatherForecastRawController.java

@@ -21,6 +21,7 @@ import com.ufo.base.framework.aspectj.lang.annotation.Log;
 import com.ufo.base.framework.aspectj.lang.enums.BusinessType;
 import com.ufo.project.forecast.shortterm.weather.domain.DataShortTermWeatherForecastRaw;
 import com.ufo.project.forecast.shortterm.weather.domain.vo.ChartDataPair;
+import com.ufo.project.forecast.shortterm.weather.domain.vo.PsfcChartExportStat;
 import com.ufo.project.forecast.shortterm.weather.domain.vo.PsfcChartResult;
 import com.ufo.project.forecast.shortterm.weather.domain.vo.PsfcChartStat;
 import com.ufo.project.forecast.shortterm.weather.domain.vo.RhsfcChartExportStat;
@@ -221,6 +222,7 @@ public class DataShortTermWeatherForecastRawController extends BaseController
     {
         PsfcChartResult forecast = dataShortTermWeatherForecastRawService.getPsfcChart(stationId, startTime, endTime);
         PsfcChartResult local = dataWeatherLocalService.getPsfcChart(stationId, startTime, endTime);
+        alignPsfcStats(forecast, local);
         return success(new ChartDataPair<PsfcChartResult>(forecast, local));
     }
 
@@ -235,16 +237,16 @@ public class DataShortTermWeatherForecastRawController extends BaseController
     {
         PsfcChartResult forecast = dataShortTermWeatherForecastRawService.getPsfcChart(stationId, startTime, endTime);
         PsfcChartResult local = dataWeatherLocalService.getPsfcChart(stationId, startTime, endTime);
-        List<PsfcChartStat> stats = new ArrayList<PsfcChartStat>();
-        if (forecast.getStats() != null)
-        {
-            stats.addAll(forecast.getStats());
-        }
-        if (local.getStats() != null)
+        alignPsfcStats(forecast, local);
+        List<PsfcChartStat> forecastStats = forecast.getStats();
+        List<PsfcChartStat> localStats = local.getStats();
+        List<PsfcChartExportStat> stats = new ArrayList<PsfcChartExportStat>();
+        for (int i = 0; i < forecastStats.size(); i++)
         {
-            stats.addAll(local.getStats());
+            stats.add(new PsfcChartExportStat(forecastStats.get(i).getTime(),
+                    forecastStats.get(i).getPsfc(), localStats.get(i).getPsfc()));
         }
-        ExcelUtil<PsfcChartStat> util = new ExcelUtil<PsfcChartStat>(PsfcChartStat.class);
+        ExcelUtil<PsfcChartExportStat> util = new ExcelUtil<PsfcChartExportStat>(PsfcChartExportStat.class);
         util.exportExcel(response, stats, "气压曲线数据");
     }
 
@@ -476,6 +478,52 @@ public class DataShortTermWeatherForecastRawController extends BaseController
         return map;
     }
 
+    /**
+     * 将预测/本地实测气压统计对齐到同一时间点并集(升序,缺数填0,等长下标一一对应)
+     */
+    private void alignPsfcStats(PsfcChartResult forecast, PsfcChartResult local)
+    {
+        Map<String, Double> forecastMap = buildPsfcTimeMap(forecast.getStats());
+        Map<String, Double> localMap = buildPsfcTimeMap(local.getStats());
+        TreeSet<String> times = new TreeSet<String>();
+        times.addAll(forecastMap.keySet());
+        times.addAll(localMap.keySet());
+        List<PsfcChartStat> forecastStats = new ArrayList<PsfcChartStat>();
+        List<PsfcChartStat> localStats = new ArrayList<PsfcChartStat>();
+        for (String time : times)
+        {
+            PsfcChartStat forecastStat = new PsfcChartStat(time, forecastMap.getOrDefault(time, 0d));
+            forecastStat.setSource("预测");
+            forecastStats.add(forecastStat);
+            PsfcChartStat localStat = new PsfcChartStat(time, localMap.getOrDefault(time, 0d));
+            localStat.setSource("本地实测");
+            localStats.add(localStat);
+        }
+        forecast.setStats(forecastStats);
+        local.setStats(localStats);
+    }
+
+    /**
+     * 按时间建立 时间->气压 映射(LinkedHashMap 保留列表序,putIfAbsent 去重取首个)
+     */
+    private Map<String, Double> buildPsfcTimeMap(List<PsfcChartStat> stats)
+    {
+        Map<String, Double> map = new LinkedHashMap<String, Double>();
+        if (stats == null)
+        {
+            return map;
+        }
+        for (PsfcChartStat stat : stats)
+        {
+            if (stat == null || stat.getTime() == null)
+            {
+                continue;
+            }
+            map.putIfAbsent(stat.getTime(), stat.getPsfc() == null ? 0d : stat.getPsfc());
+        }
+        return map;
+    }
+
     /**
      * 导出短期气象原始数据列表
      */

+ 65 - 0
forecast-backend-server/src/main/java/com/ufo/project/forecast/shortterm/weather/domain/vo/PsfcChartExportStat.java

@@ -0,0 +1,65 @@
+package com.ufo.project.forecast.shortterm.weather.domain.vo;
+
+import com.ufo.base.framework.aspectj.lang.annotation.Excel;
+
+/**
+ * 气压曲线导出行数据(预测与本地实测按时间点并集对齐,缺数填0)
+ *
+ * @author ufo
+ * @date 2026-10-29
+ */
+public class PsfcChartExportStat
+{
+    /** 时间(yyyy-MM-dd HH:mm:ss) */
+    @Excel(name = "时间")
+    private String time;
+
+    /** 预测气压(hPa) */
+    @Excel(name = "预测气压(hPa)")
+    private Double forecastPsfc;
+
+    /** 观测气压(hPa) */
+    @Excel(name = "观测气压(hPa)")
+    private Double localPsfc;
+
+    public PsfcChartExportStat()
+    {
+    }
+
+    public PsfcChartExportStat(String time, Double forecastPsfc, Double localPsfc)
+    {
+        this.time = time;
+        this.forecastPsfc = forecastPsfc;
+        this.localPsfc = localPsfc;
+    }
+
+    public String getTime()
+    {
+        return time;
+    }
+
+    public void setTime(String time)
+    {
+        this.time = time;
+    }
+
+    public Double getForecastPsfc()
+    {
+        return forecastPsfc;
+    }
+
+    public void setForecastPsfc(Double forecastPsfc)
+    {
+        this.forecastPsfc = forecastPsfc;
+    }
+
+    public Double getLocalPsfc()
+    {
+        return localPsfc;
+    }
+
+    public void setLocalPsfc(Double localPsfc)
+    {
+        this.localPsfc = localPsfc;
+    }
+}

+ 12 - 16
forecast-backend-vue/src/views/ufo/electricity/weather/PressureCurve.vue

@@ -84,8 +84,8 @@ const hasData = computed(() => !!summary.value && (summary.value.totalRecords >
 
 const columns = [
   {title: '时间', dataIndex: 'time', width: 180, align: 'center', fixed: 'left'},
-  {title: '来源', dataIndex: 'source', width: 100, align: 'center'},
-  {title: '气压(hPa)', dataIndex: 'psfc', width: 150, align: 'right'}
+  {title: '预测气压(hPa)', dataIndex: 'forecastPsfc', width: 150, align: 'right'},
+  {title: '观测气压(hPa)', dataIndex: 'localPsfc', width: 150, align: 'right'}
 ];
 
 const pagination = {
@@ -191,20 +191,16 @@ const handleQuery = async () => {
       localTotalRecords: local.totalRecords || 0,
       localValidRecords: local.validRecords || 0
     };
-    detailRows.value = [
-      ...(forecast.stats || []).map((item, index) => ({
-        key: `forecast-${index}`,
-        time: item.time,
-        source: item.source || '预测',
-        psfc: toNumber(item.psfc, 0)
-      })),
-      ...(local.stats || []).map((item, index) => ({
-        key: `local-${index}`,
-        time: item.time,
-        source: item.source || '观测',
-        psfc: toNumber(item.psfc, 0)
-      }))
-    ];
+    // 后端已将 forecast/local 的 stats 对齐到同一时间点并集(缺数填0),按下标对齐取行
+    const forecastStats = forecast.stats || [];
+    const localStats = local.stats || [];
+    const rowCount = Math.max(forecastStats.length, localStats.length);
+    detailRows.value = Array.from({ length: rowCount }, (_, index) => ({
+      key: `row-${index}`,
+      time: forecastStats[index]?.time || localStats[index]?.time,
+      forecastPsfc: toNumber(forecastStats[index]?.psfc, 0),
+      localPsfc: toNumber(localStats[index]?.psfc, 0)
+    }));
     renderChart(forecast.stats || [], local.stats || []);
   } finally {
     loading.value = false;