Преглед на файлове

[1015] 功率预报数据文件同步优化: raw写入同时upsert下发/上报表(report仅batch_no为空行)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
taosj преди 2 седмици
родител
ревизия
b4ab237c9b
променени са 13 файла, в които са добавени 463 реда и са изтрити 30 реда
  1. 149 27
      forecast-backend-server/src/main/java/com/ufo/project/data/processer/DataFileProcesserPowerImpl.java
  2. 24 0
      forecast-backend-server/src/main/java/com/ufo/project/forecast/mediumterm/power/mapper/DataMediumTermPowerForecastIssuedMapper.java
  3. 24 0
      forecast-backend-server/src/main/java/com/ufo/project/forecast/mediumterm/power/mapper/DataMediumTermPowerForecastReportMapper.java
  4. 24 0
      forecast-backend-server/src/main/java/com/ufo/project/forecast/shortterm/power/mapper/DataShortTermPowerForecastIssuedMapper.java
  5. 16 0
      forecast-backend-server/src/main/java/com/ufo/project/forecast/shortterm/power/mapper/DataShortTermPowerForecastReportMapper.java
  6. 24 0
      forecast-backend-server/src/main/java/com/ufo/project/forecast/supershort/mapper/DataSuperShortTermForecastIssuedMapper.java
  7. 16 0
      forecast-backend-server/src/main/java/com/ufo/project/forecast/supershort/mapper/DataSuperShortTermForecastReportMapper.java
  8. 38 1
      forecast-backend-server/src/main/resources/mybatis/mediumpower/DataMediumTermPowerForecastIssuedMapper.xml
  9. 30 0
      forecast-backend-server/src/main/resources/mybatis/mediumpower/DataMediumTermPowerForecastReportMapper.xml
  10. 38 1
      forecast-backend-server/src/main/resources/mybatis/power/DataShortTermPowerForecastIssuedMapper.xml
  11. 21 0
      forecast-backend-server/src/main/resources/mybatis/power/DataShortTermPowerForecastReportMapper.xml
  12. 38 1
      forecast-backend-server/src/main/resources/mybatis/supershort/DataSuperShortTermForecastIssuedMapper.xml
  13. 21 0
      forecast-backend-server/src/main/resources/mybatis/supershort/DataSuperShortTermForecastReportMapper.xml

+ 149 - 27
forecast-backend-server/src/main/java/com/ufo/project/data/processer/DataFileProcesserPowerImpl.java

@@ -30,13 +30,25 @@ import com.ufo.base.common.utils.StringUtils;
 import com.ufo.module.system.domain.SysDictData;
 import com.ufo.project.config.domain.ConfigStation;
 import com.ufo.project.data.domain.DataFileSyncFiles;
+import com.ufo.project.forecast.mediumterm.power.domain.DataMediumTermPowerForecastIssued;
 import com.ufo.project.forecast.mediumterm.power.domain.DataMediumTermPowerForecastRaw;
+import com.ufo.project.forecast.mediumterm.power.domain.DataMediumTermPowerForecastReport;
+import com.ufo.project.forecast.mediumterm.power.mapper.DataMediumTermPowerForecastIssuedMapper;
 import com.ufo.project.forecast.mediumterm.power.mapper.DataMediumTermPowerForecastRawMapper;
+import com.ufo.project.forecast.mediumterm.power.mapper.DataMediumTermPowerForecastReportMapper;
+import com.ufo.project.forecast.shortterm.power.domain.DataShortTermPowerForecastIssued;
 import com.ufo.project.forecast.shortterm.power.domain.DataShortTermPowerForecastRaw;
+import com.ufo.project.forecast.shortterm.power.domain.DataShortTermPowerForecastReport;
+import com.ufo.project.forecast.shortterm.power.mapper.DataShortTermPowerForecastIssuedMapper;
 import com.ufo.project.forecast.shortterm.power.mapper.DataShortTermPowerForecastRawMapper;
+import com.ufo.project.forecast.shortterm.power.mapper.DataShortTermPowerForecastReportMapper;
+import com.ufo.project.forecast.supershort.domain.DataSuperShortTermForecastIssued;
 import com.ufo.project.forecast.supershort.domain.DataSuperShortTermForecastRaw;
+import com.ufo.project.forecast.supershort.domain.DataSuperShortTermForecastReport;
 import com.ufo.project.forecast.supershort.domain.DataUltraShortTermPowerForecasting;
+import com.ufo.project.forecast.supershort.mapper.DataSuperShortTermForecastIssuedMapper;
 import com.ufo.project.forecast.supershort.mapper.DataSuperShortTermForecastRawMapper;
+import com.ufo.project.forecast.supershort.mapper.DataSuperShortTermForecastReportMapper;
 import com.ufo.project.forecast.supershort.mapper.DataUltraShortTermPowerForecastingMapper;
 
 /**
@@ -44,14 +56,14 @@ import com.ufo.project.forecast.supershort.mapper.DataUltraShortTermPowerForecas
  *
  * 处理形如 {@code /home/power/upload/power/JMJD01/MediumTerm/2026-09-2026090312.csv} 的功率csv文件:
  * 1. 逐级目录匹配字典 station_file_code_mapping(场站编码-文件映射)的key, 取value为场站编码;
- * 2. 目录含 MediumTerm 为中期、ShortTerm 为短期、UltraShortTerm 为超短期(优先判定), 分别写入
+ * 2. 目录含 MediumTerm 为中期、ShortTerm 为短期、UltraShortTerm 为超短期(优先判定), 分别 upsert
  *    data_medium_term_power_forecast_raw / data_short_term_power_forecast_raw /
- *    data_super_short_term_forecast_raw;
+ *    data_super_short_term_forecast_raw 及对应 _issued / _report 表(report表仅batch_no为空的行);
  * 3. 文件名中 yyyyMMddHH(超短期为yyyyMMddHHmm, 已是UTC)转为起报时间start_time(epoch秒);
  * 4. EasyExcel读csv, 按fieldMappingConfig映射(time -> forecast_time, ISO格式如 2026-09-19T12:00Z,
  *    本身即UTC; power -> power), 经纬度/场站等其余字段按任务约定取固定元数据与场站信息;
- * 5. 按(station_id, start_time)查询已有记录, 以(start_time, forecast_time)匹配,
- *    已存在的批量更新power, 新数据批量插入, 每500条一批.
+ * 5. 每张目标表按场站字段(raw按station_id, issued/report按entity_id)与start_time查询已有记录,
+ *    以forecast_time匹配, 已存在的批量更新power, 新数据批量插入, 每500条一批.
  *
  * @author ufo
  * @date 2026-09-22
@@ -126,6 +138,24 @@ public class DataFileProcesserPowerImpl extends AbstraceDataFileProcesser
     @Autowired
     private DataUltraShortTermPowerForecastingMapper dataUltraShortTermPowerForecastingMapper;
 
+    @Autowired
+    private DataShortTermPowerForecastIssuedMapper dataShortTermPowerForecastIssuedMapper;
+
+    @Autowired
+    private DataShortTermPowerForecastReportMapper dataShortTermPowerForecastReportMapper;
+
+    @Autowired
+    private DataMediumTermPowerForecastIssuedMapper dataMediumTermPowerForecastIssuedMapper;
+
+    @Autowired
+    private DataMediumTermPowerForecastReportMapper dataMediumTermPowerForecastReportMapper;
+
+    @Autowired
+    private DataSuperShortTermForecastIssuedMapper dataSuperShortTermForecastIssuedMapper;
+
+    @Autowired
+    private DataSuperShortTermForecastReportMapper dataSuperShortTermForecastReportMapper;
+
     @Override
     protected String parseAndSave(DataFileSyncFiles file)
     {
@@ -165,7 +195,7 @@ public class DataFileProcesserPowerImpl extends AbstraceDataFileProcesser
             return "csv无有效数据行";
         }
 
-        int[] result = new int[]{0, 0};
+        int[] result = new int[6];
         switch (term.kind)
         {
             case SHORT:
@@ -181,8 +211,8 @@ public class DataFileProcesserPowerImpl extends AbstraceDataFileProcesser
             default:
                 break;
         }
-        log.info("[DataFileProcesserPower] 处理完成, file={}, 场站={}, {}, start_time={}, 更新{}条, 新增{}条",
-                csvFile.getName(), stationCode, term.subjectName, startTime, result[0], result[1]);
+        log.info("[DataFileProcesserPower] 处理完成, file={}, 场站={}, {}, start_time={}, raw更新{}新增{}, 下发更新{}新增{}, 上报更新{}新增{}",
+                csvFile.getName(), stationCode, term.subjectName, startTime, result[0], result[1], result[2], result[3], result[4], result[5]);
         return "";
     }
 
@@ -310,45 +340,96 @@ public class DataFileProcesserPowerImpl extends AbstraceDataFileProcesser
     }
 
     /**
-     * 短期: 查重分类 + 500一批更新/插入 data_short_term_power_forecast_raw
+     * 短期: raw/issued/report 三表各做一次查重分类 + 500一批更新/插入
      *
-     * @return int[]{更新条数, 新增条数}
+     * @return int[]{raw更新, raw新增, issued更新, issued新增, report更新, report新增}
      */
     private int[] saveShortTerm(Term term, ConfigStation station, long startTime, Map<Long, String> powerByForecastTime)
     {
-        return saveTerm(term, station, startTime, powerByForecastTime,
+        int[] raw = saveTerm(term, station, startTime, powerByForecastTime,
+                "stationId", station.getId(),
                 DataShortTermPowerForecastRaw::new,
                 dataShortTermPowerForecastRawMapper::selectDataShortTermPowerForecastRawList,
+                (row, forecastTime, power) -> fillPowerCommon(row, term, station, startTime, forecastTime, power),
                 dataShortTermPowerForecastRawMapper::batchUpdateDataShortTermPowerForecastRaw,
                 dataShortTermPowerForecastRawMapper::batchInsertDataShortTermPowerForecastRaw);
+        int[] issued = saveTerm(term, station, startTime, powerByForecastTime,
+                "entityId", String.valueOf(station.getId()),
+                DataShortTermPowerForecastIssued::new,
+                dataShortTermPowerForecastIssuedMapper::selectByEntityAndStartTime,
+                (row, forecastTime, power) -> fillIssuedReport(row, term, station, startTime, forecastTime, power, false),
+                dataShortTermPowerForecastIssuedMapper::batchUpdateDataShortTermPowerForecastIssued,
+                dataShortTermPowerForecastIssuedMapper::batchInsertDataShortTermPowerForecastIssued);
+        int[] report = saveTerm(term, station, startTime, powerByForecastTime,
+                "entityId", String.valueOf(station.getId()),
+                DataShortTermPowerForecastReport::new,
+                dataShortTermPowerForecastReportMapper::selectByEntityAndStartTime,
+                (row, forecastTime, power) -> fillIssuedReport(row, term, station, startTime, forecastTime, power, true),
+                dataShortTermPowerForecastReportMapper::batchUpdateDataShortTermPowerForecastReport,
+                dataShortTermPowerForecastReportMapper::insertBatch);
+        return new int[]{raw[0], raw[1], issued[0], issued[1], report[0], report[1]};
     }
 
     /**
-     * 中期: 查重分类 + 500一批更新/插入 data_medium_term_power_forecast_raw
+     * 中期: raw/issued/report 三表各做一次查重分类 + 500一批更新/插入
      *
-     * @return int[]{更新条数, 新增条数}
+     * @return int[]{raw更新, raw新增, issued更新, issued新增, report更新, report新增}
      */
     private int[] saveMediumTerm(Term term, ConfigStation station, long startTime, Map<Long, String> powerByForecastTime)
     {
-        return saveTerm(term, station, startTime, powerByForecastTime,
+        int[] raw = saveTerm(term, station, startTime, powerByForecastTime,
+                "stationId", station.getId(),
                 DataMediumTermPowerForecastRaw::new,
                 dataMediumTermPowerForecastRawMapper::selectDataMediumTermPowerForecastRawList,
+                (row, forecastTime, power) -> fillPowerCommon(row, term, station, startTime, forecastTime, power),
                 dataMediumTermPowerForecastRawMapper::batchUpdateDataMediumTermPowerForecastRaw,
                 dataMediumTermPowerForecastRawMapper::batchInsertDataMediumTermPowerForecastRaw);
+        int[] issued = saveTerm(term, station, startTime, powerByForecastTime,
+                "entityId", String.valueOf(station.getId()),
+                DataMediumTermPowerForecastIssued::new,
+                dataMediumTermPowerForecastIssuedMapper::selectByEntityAndStartTime,
+                (row, forecastTime, power) -> fillIssuedReport(row, term, station, startTime, forecastTime, power, false),
+                dataMediumTermPowerForecastIssuedMapper::batchUpdateDataMediumTermPowerForecastIssued,
+                dataMediumTermPowerForecastIssuedMapper::batchInsertDataMediumTermPowerForecastIssued);
+        int[] report = saveTerm(term, station, startTime, powerByForecastTime,
+                "entityId", String.valueOf(station.getId()),
+                DataMediumTermPowerForecastReport::new,
+                dataMediumTermPowerForecastReportMapper::selectByEntityAndStartTime,
+                (row, forecastTime, power) -> fillIssuedReport(row, term, station, startTime, forecastTime, power, true),
+                dataMediumTermPowerForecastReportMapper::batchUpdateDataMediumTermPowerForecastReport,
+                dataMediumTermPowerForecastReportMapper::insertBatch);
+        return new int[]{raw[0], raw[1], issued[0], issued[1], report[0], report[1]};
     }
 
     /**
-     * 超短期: 查重分类 + 500一批更新/插入 data_super_short_term_forecast_raw
+     * 超短期: raw/issued/report 三表各做一次查重分类 + 500一批更新/插入
      *
-     * @return int[]{更新条数, 新增条数}
+     * @return int[]{raw更新, raw新增, issued更新, issued新增, report更新, report新增}
      */
     private int[] saveUltraShortTerm(Term term, ConfigStation station, long startTime, Map<Long, String> powerByForecastTime)
     {
-        return saveTerm(term, station, startTime, powerByForecastTime,
+        int[] raw = saveTerm(term, station, startTime, powerByForecastTime,
+                "stationId", station.getId(),
                 DataSuperShortTermForecastRaw::new,
                 dataSuperShortTermForecastRawMapper::selectDataSuperShortTermForecastRawList,
+                (row, forecastTime, power) -> fillPowerCommon(row, term, station, startTime, forecastTime, power),
                 dataSuperShortTermForecastRawMapper::batchUpdateDataSuperShortTermForecastRaw,
                 dataSuperShortTermForecastRawMapper::batchInsertDataSuperShortTermForecastRaw);
+        int[] issued = saveTerm(term, station, startTime, powerByForecastTime,
+                "entityId", String.valueOf(station.getId()),
+                DataSuperShortTermForecastIssued::new,
+                dataSuperShortTermForecastIssuedMapper::selectByEntityAndStartTime,
+                (row, forecastTime, power) -> fillIssuedReport(row, term, station, startTime, forecastTime, power, false),
+                dataSuperShortTermForecastIssuedMapper::batchUpdateDataSuperShortTermForecastIssued,
+                dataSuperShortTermForecastIssuedMapper::batchInsertDataSuperShortTermForecastIssued);
+        int[] report = saveTerm(term, station, startTime, powerByForecastTime,
+                "entityId", String.valueOf(station.getId()),
+                DataSuperShortTermForecastReport::new,
+                dataSuperShortTermForecastReportMapper::selectByEntityAndStartTime,
+                (row, forecastTime, power) -> fillIssuedReport(row, term, station, startTime, forecastTime, power, true),
+                dataSuperShortTermForecastReportMapper::batchUpdateDataSuperShortTermForecastReport,
+                dataSuperShortTermForecastReportMapper::insertBatch);
+        return new int[]{raw[0], raw[1], issued[0], issued[1], report[0], report[1]};
     }
 
     /**
@@ -411,18 +492,18 @@ public class DataFileProcesserPowerImpl extends AbstraceDataFileProcesser
     }
 
     /**
-     * 三条链路共用: 按(station_id, start_time)查已有记录, 以forecast_time匹配,
-     * 已有置Id进更新组、其余进插入组, 各按BATCH_SIZE一批写库;
-     * 三类实体无公共父类故stationId/startTime/Id/forecastTime经反射读写(与fillPowerCommon同法)
+     * 共用upsert: 按stationField/stationValue与start_time查已有记录, 以forecast_time匹配,
+     * 已有置Id进更新组、其余经rowFiller填充后进插入组, 各按BATCH_SIZE一批写库;
+     * 各表实体无公共父类故字段经反射读写(与fillPowerCommon同法)
      *
      * @return int[]{更新条数, 新增条数}
      */
     private <T> int[] saveTerm(Term term, ConfigStation station, long startTime, Map<Long, String> powerByForecastTime,
-            Supplier<T> factory, Function<T, List<T>> selectList,
-            Consumer<List<T>> batchUpdate, Consumer<List<T>> batchInsert)
+            String stationField, Object stationValue, Supplier<T> factory, Function<T, List<T>> selectList,
+            RowFiller rowFiller, Consumer<List<T>> batchUpdate, Consumer<List<T>> batchInsert)
     {
         T query = factory.get();
-        setEntityField(query, "stationId", station.getId());
+        setEntityField(query, stationField, stationValue);
         setEntityField(query, "startTime", startTime);
         List<T> dbList = selectList.apply(query);
         Map<Long, Long> existIds = new HashMap<>();
@@ -439,17 +520,17 @@ public class DataFileProcesserPowerImpl extends AbstraceDataFileProcesser
         List<T> newList = new ArrayList<>();
         for (Map.Entry<Long, String> row : powerByForecastTime.entrySet())
         {
-            T raw = factory.get();
-            fillPowerCommon(raw, term, station, startTime, row.getKey(), row.getValue());
+            T entity = factory.get();
+            rowFiller.fill(entity, row.getKey(), row.getValue());
             Long existId = existIds.get(row.getKey());
             if (existId != null)
             {
-                setEntityField(raw, "Id", existId);
-                dbExistList.add(raw);
+                setEntityField(entity, "Id", existId);
+                dbExistList.add(entity);
             }
             else
             {
-                newList.add(raw);
+                newList.add(entity);
             }
         }
         for (List<T> batch : partition(dbExistList, BATCH_SIZE))
@@ -507,6 +588,40 @@ public class DataFileProcesserPowerImpl extends AbstraceDataFileProcesser
         }
     }
 
+    /**
+     * 写入issued/report两表链路共有的元数据/场站/时间/功率字段(字段同名, 无公共父类故用反射);
+     * predays短中期写入, preQrts仅超短期; batch_no恒不写(置空),
+     * createTimeEpoch仅短/超短期report实体存在该字段且insertBatch按列取值, 中期report由库端取当前epoch秒
+     */
+    void fillIssuedReport(Object row, Term term, ConfigStation station, long startTime, long forecastTime, String power, boolean isReport)
+    {
+        Map<String, Object> values = new LinkedHashMap<>();
+        values.put("dataSourcegrabId", term.id);
+        values.put("dataSourcegrabPatternName", term.patternName);
+        values.put("entityId", String.valueOf(station.getId()));
+        values.put("entityType", 1L);
+        values.put("entityName", station.getStationName());
+        values.put("startTime", startTime);
+        values.put("forecastTime", forecastTime);
+        if (term.kind == Kind.ULTRA)
+        {
+            values.put("preQrts", term.preQrts);
+        }
+        else
+        {
+            values.put("predays", term.preDays);
+        }
+        if (isReport && term.kind != Kind.MEDIUM)
+        {
+            values.put("createTimeEpoch", System.currentTimeMillis() / 1000);
+        }
+        values.put("power", power);
+        for (Map.Entry<String, Object> value : values.entrySet())
+        {
+            setEntityField(row, value.getKey(), value.getValue());
+        }
+    }
+
     /**
      * 解析文件名时间戳为起报epoch秒(UTC): 短期/中期10位yyyyMMddHH, 超短期12位yyyyMMddHHmm
      */
@@ -578,6 +693,13 @@ public class DataFileProcesserPowerImpl extends AbstraceDataFileProcesser
         }
     }
 
+    /** upsert行填充器: 按预测时间/功率填充一条新实体 */
+    @FunctionalInterface
+    interface RowFiller
+    {
+        void fill(Object entity, long forecastTime, String power);
+    }
+
     /** 时效类型(路由到各自保存链路与实体) */
     enum Kind
     {

+ 24 - 0
forecast-backend-server/src/main/java/com/ufo/project/forecast/mediumterm/power/mapper/DataMediumTermPowerForecastIssuedMapper.java

@@ -81,4 +81,28 @@ public interface DataMediumTermPowerForecastIssuedMapper
      */
     public List<DataMediumTermPowerForecastIssued> selectLatestByTimeRange(@Param("entityId") String entityId,
             @Param("startTime") Long startTime, @Param("endTime") Long endTime);
+
+    /**
+     * 按entity_id与start_time精确匹配查询场站下发数据(供upsert查重)
+     *
+     * @param dataMediumTermPowerForecastIssued 查询条件(entityId, startTime)
+     * @return 预测功率下发数据集合(按forecast_time升序)
+     */
+    public List<DataMediumTermPowerForecastIssued> selectByEntityAndStartTime(DataMediumTermPowerForecastIssued dataMediumTermPowerForecastIssued);
+
+    /**
+     * 批量新增下发数据(固定列, create_time取库端当前epoch秒)
+     *
+     * @param list 预测功率下发数据集合
+     * @return 结果
+     */
+    public int batchInsertDataMediumTermPowerForecastIssued(@Param("list") List<DataMediumTermPowerForecastIssued> list);
+
+    /**
+     * 批量按下键修改下发数据(仅更新预测功率)
+     *
+     * @param list 预测功率下发数据集合
+     * @return 结果
+     */
+    public int batchUpdateDataMediumTermPowerForecastIssued(@Param("list") List<DataMediumTermPowerForecastIssued> list);
 }

+ 24 - 0
forecast-backend-server/src/main/java/com/ufo/project/forecast/mediumterm/power/mapper/DataMediumTermPowerForecastReportMapper.java

@@ -70,4 +70,28 @@ public interface DataMediumTermPowerForecastReportMapper
      * @return 最新功率预测数据列表(按 forecast_time 升序)
      */
     public List<DataMediumTermPowerForecastReport> selectLatestForecastList(@Param("entityId") String entityId, @Param("startTime") Long startTime, @Param("endTime") Long endTime);
+
+    /**
+     * 按entity_id与start_time精确匹配查询场站上报数据(供upsert查重)
+     *
+     * @param dataMediumTermPowerForecastReport 查询条件(entityId, startTime)
+     * @return 上报数据集合(按forecast_time升序)
+     */
+    public List<DataMediumTermPowerForecastReport> selectByEntityAndStartTime(DataMediumTermPowerForecastReport dataMediumTermPowerForecastReport);
+
+    /**
+     * 批量按下键修改上报数据(仅更新预测功率)
+     *
+     * @param list 上报数据集合
+     * @return 结果
+     */
+    public int batchUpdateDataMediumTermPowerForecastReport(@Param("list") List<DataMediumTermPowerForecastReport> list);
+
+    /**
+     * 批量新增上报数据(固定列, create_time取库端当前epoch秒)
+     *
+     * @param list 上报数据集合
+     * @return 结果
+     */
+    public int insertBatch(@Param("list") List<DataMediumTermPowerForecastReport> list);
 }

+ 24 - 0
forecast-backend-server/src/main/java/com/ufo/project/forecast/shortterm/power/mapper/DataShortTermPowerForecastIssuedMapper.java

@@ -104,4 +104,28 @@ public interface DataShortTermPowerForecastIssuedMapper
      */
     public List<DataShortTermPowerForecastIssued> selectLatestByWindow(@Param("entityId") String entityId,
             @Param("windowStart") Long windowStart, @Param("windowEnd") Long windowEnd);
+
+    /**
+     * 按entity_id与start_time精确匹配查询场站下发数据(供upsert查重)
+     *
+     * @param dataShortTermPowerForecastIssued 查询条件(entityId, startTime)
+     * @return 预测功率下发数据集合(按forecast_time升序)
+     */
+    public List<DataShortTermPowerForecastIssued> selectByEntityAndStartTime(DataShortTermPowerForecastIssued dataShortTermPowerForecastIssued);
+
+    /**
+     * 批量新增下发数据(固定列, create_time取库端当前epoch秒)
+     *
+     * @param list 预测功率下发数据集合
+     * @return 结果
+     */
+    public int batchInsertDataShortTermPowerForecastIssued(@Param("list") List<DataShortTermPowerForecastIssued> list);
+
+    /**
+     * 批量按下键修改下发数据(仅更新预测功率)
+     *
+     * @param list 预测功率下发数据集合
+     * @return 结果
+     */
+    public int batchUpdateDataShortTermPowerForecastIssued(@Param("list") List<DataShortTermPowerForecastIssued> list);
 }

+ 16 - 0
forecast-backend-server/src/main/java/com/ufo/project/forecast/shortterm/power/mapper/DataShortTermPowerForecastReportMapper.java

@@ -99,4 +99,20 @@ public interface DataShortTermPowerForecastReportMapper
      * @return 结果
      */
     public int insertBatch(@Param("list") List<DataShortTermPowerForecastReport> list);
+
+    /**
+     * 按entity_id与start_time精确匹配查询场站上报数据(仅batch_no为空的行, 供upsert查重)
+     *
+     * @param dataShortTermPowerForecastReport 查询条件(entityId, startTime)
+     * @return 上报数据集合(按forecast_time升序)
+     */
+    public List<DataShortTermPowerForecastReport> selectByEntityAndStartTime(DataShortTermPowerForecastReport dataShortTermPowerForecastReport);
+
+    /**
+     * 批量按下键修改上报数据(仅更新预测功率, 仅作用于batch_no为空的行)
+     *
+     * @param list 上报数据集合
+     * @return 结果
+     */
+    public int batchUpdateDataShortTermPowerForecastReport(@Param("list") List<DataShortTermPowerForecastReport> list);
 }

+ 24 - 0
forecast-backend-server/src/main/java/com/ufo/project/forecast/supershort/mapper/DataSuperShortTermForecastIssuedMapper.java

@@ -81,4 +81,28 @@ public interface DataSuperShortTermForecastIssuedMapper
      */
     public List<DataSuperShortTermForecastIssued> selectLatestByWindow(@Param("entityId") String entityId,
             @Param("windowStart") Long windowStart, @Param("windowEnd") Long windowEnd);
+
+    /**
+     * 按entity_id与start_time精确匹配查询场站下发数据(供upsert查重)
+     *
+     * @param dataSuperShortTermForecastIssued 查询条件(entityId, startTime)
+     * @return 预测功率下发数据集合(按forecast_time升序)
+     */
+    public List<DataSuperShortTermForecastIssued> selectByEntityAndStartTime(DataSuperShortTermForecastIssued dataSuperShortTermForecastIssued);
+
+    /**
+     * 批量新增下发数据(固定列, create_time取库端当前epoch秒)
+     *
+     * @param list 预测功率下发数据集合
+     * @return 结果
+     */
+    public int batchInsertDataSuperShortTermForecastIssued(@Param("list") List<DataSuperShortTermForecastIssued> list);
+
+    /**
+     * 批量按下键修改下发数据(仅更新预测功率)
+     *
+     * @param list 预测功率下发数据集合
+     * @return 结果
+     */
+    public int batchUpdateDataSuperShortTermForecastIssued(@Param("list") List<DataSuperShortTermForecastIssued> list);
 }

+ 16 - 0
forecast-backend-server/src/main/java/com/ufo/project/forecast/supershort/mapper/DataSuperShortTermForecastReportMapper.java

@@ -97,4 +97,20 @@ public interface DataSuperShortTermForecastReportMapper
      * @return 结果
      */
     public int insertBatch(@Param("list") List<DataSuperShortTermForecastReport> list);
+
+    /**
+     * 按entity_id与start_time精确匹配查询场站上报数据(仅batch_no为空的行, 供upsert查重)
+     *
+     * @param dataSuperShortTermForecastReport 查询条件(entityId, startTime)
+     * @return 上报数据集合(按forecast_time升序)
+     */
+    public List<DataSuperShortTermForecastReport> selectByEntityAndStartTime(DataSuperShortTermForecastReport dataSuperShortTermForecastReport);
+
+    /**
+     * 批量按下键修改上报数据(仅更新预测功率, 仅作用于batch_no为空的行)
+     *
+     * @param list 上报数据集合
+     * @return 结果
+     */
+    public int batchUpdateDataSuperShortTermForecastReport(@Param("list") List<DataSuperShortTermForecastReport> list);
 }

+ 38 - 1
forecast-backend-server/src/main/resources/mybatis/mediumpower/DataMediumTermPowerForecastIssuedMapper.xml

@@ -123,9 +123,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </select>
 
     <delete id="deleteDataMediumTermPowerForecastIssuedByIds" parameterType="String">
-        delete from data_medium_term_power_forecast_issued where _id in 
+        delete from data_medium_term_power_forecast_issued where _id in
         <foreach item="Id" collection="array" open="(" separator="," close=")">
             #{Id}
         </foreach>
     </delete>
+
+    <!-- 按entity_id与start_time精确匹配查询场站下发数据(供upsert查重) -->
+    <select id="selectByEntityAndStartTime" parameterType="DataMediumTermPowerForecastIssued" resultMap="DataMediumTermPowerForecastIssuedResult">
+        <include refid="selectDataMediumTermPowerForecastIssuedVo"/>
+        where entity_id = #{entityId}
+          and start_time = #{startTime}
+        order by forecast_time asc
+    </select>
+
+    <!-- 批量新增下发数据(功率数据文件处理器): create_time 取库端当前epoch秒(列为INTEGER) -->
+    <insert id="batchInsertDataMediumTermPowerForecastIssued" parameterType="java.util.List">
+        insert into data_medium_term_power_forecast_issued (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name, create_time,
+            start_time, forecast_time, predays, power
+        ) values
+        <foreach collection="list" item="item" separator=",">
+            (
+                #{item.dataSourcegrabId}, #{item.dataSourcegrabPatternName},
+                #{item.entityId}, #{item.entityType,jdbcType=BIGINT}, #{item.entityName,jdbcType=VARCHAR}, EXTRACT(EPOCH FROM now())::INTEGER,
+                #{item.startTime}, #{item.forecastTime},
+                #{item.predays}, #{item.power,jdbcType=VARCHAR}
+            )
+        </foreach>
+    </insert>
+
+    <!-- 批量修改下发数据(功率数据文件处理器): 按_id更新预测功率 -->
+    <update id="batchUpdateDataMediumTermPowerForecastIssued" parameterType="java.util.List">
+        update data_medium_term_power_forecast_issued as t
+        set power = v.power
+        from (values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.Id}::bigint, #{item.power,jdbcType=VARCHAR}::varchar)
+        </foreach>
+        ) as v(_id, power)
+        where t._id = v._id
+    </update>
 </mapper>

+ 30 - 0
forecast-backend-server/src/main/resources/mybatis/mediumpower/DataMediumTermPowerForecastReportMapper.xml

@@ -117,4 +117,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
           and forecast_time - start_time = 864000
         ORDER BY forecast_time asc, start_time desc, _id DESC
     </select>
+
+    <!-- 按entity_id与start_time精确匹配查询场站上报数据(供upsert查重) -->
+    <select id="selectByEntityAndStartTime" parameterType="DataMediumTermPowerForecastReport" resultMap="DataMediumTermPowerForecastReportResult">
+        <include refid="selectDataMediumTermPowerForecastReportVo"/>
+        where entity_id = #{entityId}
+          and start_time = #{startTime}
+        order by forecast_time asc
+    </select>
+
+    <!-- 批量修改上报数据(功率数据文件处理器): 按_id更新预测功率 -->
+    <update id="batchUpdateDataMediumTermPowerForecastReport" parameterType="java.util.List">
+        update data_medium_term_power_forecast_report as t
+        set power = v.power
+        from (values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.Id}::bigint, #{item.power,jdbcType=VARCHAR}::varchar)
+        </foreach>
+        ) as v(_id, power)
+        where t._id = v._id
+    </update>
+
+    <!-- 批量新增上报数据(功率数据文件处理器): create_time 取库端当前epoch秒(列为INTEGER) -->
+    <insert id="insertBatch" parameterType="list">
+        insert into data_medium_term_power_forecast_report
+        (data_sourcegrab_id, data_sourcegrab_pattern_name, entity_id, entity_type, entity_name, create_time, start_time, forecast_time, predays, power)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.dataSourcegrabId}, #{item.dataSourcegrabPatternName}, #{item.entityId}, #{item.entityType}, #{item.entityName}, EXTRACT(EPOCH FROM now())::INTEGER, #{item.startTime}, #{item.forecastTime}, #{item.predays}, #{item.power})
+        </foreach>
+    </insert>
 </mapper>

+ 38 - 1
forecast-backend-server/src/main/resources/mybatis/power/DataShortTermPowerForecastIssuedMapper.xml

@@ -151,9 +151,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </select>
 
     <delete id="deleteDataShortTermPowerForecastIssuedByIds" parameterType="String">
-        delete from data_short_term_power_forecast_issued where _id in 
+        delete from data_short_term_power_forecast_issued where _id in
         <foreach item="Id" collection="array" open="(" separator="," close=")">
             #{Id}
         </foreach>
     </delete>
+
+    <!-- 按entity_id与start_time精确匹配查询场站下发数据(供upsert查重) -->
+    <select id="selectByEntityAndStartTime" parameterType="DataShortTermPowerForecastIssued" resultMap="DataShortTermPowerForecastIssuedResult">
+        <include refid="selectDataShortTermPowerForecastIssuedVo"/>
+        where entity_id = #{entityId}
+          and start_time = #{startTime}
+        order by forecast_time asc
+    </select>
+
+    <!-- 批量新增下发数据(功率数据文件处理器): create_time 取库端当前epoch秒(列为INTEGER) -->
+    <insert id="batchInsertDataShortTermPowerForecastIssued" parameterType="java.util.List">
+        insert into data_short_term_power_forecast_issued (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name, create_time,
+            start_time, forecast_time, predays, power
+        ) values
+        <foreach collection="list" item="item" separator=",">
+            (
+                #{item.dataSourcegrabId}, #{item.dataSourcegrabPatternName},
+                #{item.entityId}, #{item.entityType,jdbcType=BIGINT}, #{item.entityName,jdbcType=VARCHAR}, EXTRACT(EPOCH FROM now())::INTEGER,
+                #{item.startTime}, #{item.forecastTime},
+                #{item.predays}, #{item.power,jdbcType=VARCHAR}
+            )
+        </foreach>
+    </insert>
+
+    <!-- 批量修改下发数据(功率数据文件处理器): 按_id更新预测功率 -->
+    <update id="batchUpdateDataShortTermPowerForecastIssued" parameterType="java.util.List">
+        update data_short_term_power_forecast_issued as t
+        set power = v.power
+        from (values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.Id}::bigint, #{item.power,jdbcType=VARCHAR}::varchar)
+        </foreach>
+        ) as v(_id, power)
+        where t._id = v._id
+    </update>
 </mapper>

+ 21 - 0
forecast-backend-server/src/main/resources/mybatis/power/DataShortTermPowerForecastReportMapper.xml

@@ -152,4 +152,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             (#{item.dataSourcegrabId}, #{item.dataSourcegrabPatternName}, #{item.entityId}, #{item.entityType}, #{item.entityName}, #{item.createTimeEpoch}, #{item.startTime}, #{item.forecastTime}, #{item.predays}, #{item.power}, #{item.batchNo})
         </foreach>
     </insert>
+
+    <!-- 按entity_id与start_time精确匹配查询场站上报数据(仅batch_no为空的行, 供upsert查重) -->
+    <select id="selectByEntityAndStartTime" parameterType="DataShortTermPowerForecastReport" resultMap="DataShortTermPowerForecastReportResult">
+        <include refid="selectDataShortTermPowerForecastReportVo"/>
+        where entity_id = #{entityId}
+          and start_time = #{startTime}
+          and batch_no is null
+        order by forecast_time asc
+    </select>
+
+    <!-- 批量修改上报数据(功率数据文件处理器): 按_id更新预测功率, 仅作用于batch_no为空的行 -->
+    <update id="batchUpdateDataShortTermPowerForecastReport" parameterType="java.util.List">
+        update data_short_term_power_forecast_report as t
+        set power = v.power
+        from (values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.Id}::bigint, #{item.power,jdbcType=VARCHAR}::varchar)
+        </foreach>
+        ) as v(_id, power)
+        where t._id = v._id and t.batch_no is null
+    </update>
 </mapper>

+ 38 - 1
forecast-backend-server/src/main/resources/mybatis/supershort/DataSuperShortTermForecastIssuedMapper.xml

@@ -116,9 +116,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </select>
 
     <delete id="deleteDataSuperShortTermForecastIssuedByIds" parameterType="String">
-        delete from data_super_short_term_forecast_issued where _id in 
+        delete from data_super_short_term_forecast_issued where _id in
         <foreach item="Id" collection="array" open="(" separator="," close=")">
             #{Id}
         </foreach>
     </delete>
+
+    <!-- 按entity_id与start_time精确匹配查询场站下发数据(供upsert查重) -->
+    <select id="selectByEntityAndStartTime" parameterType="DataSuperShortTermForecastIssued" resultMap="DataSuperShortTermForecastIssuedResult">
+        <include refid="selectDataSuperShortTermForecastIssuedVo"/>
+        where entity_id = #{entityId}
+          and start_time = #{startTime}
+        order by forecast_time asc
+    </select>
+
+    <!-- 批量新增下发数据(功率数据文件处理器): create_time 取库端当前epoch秒(列为INTEGER) -->
+    <insert id="batchInsertDataSuperShortTermForecastIssued" parameterType="java.util.List">
+        insert into data_super_short_term_forecast_issued (
+            data_sourcegrab_id, data_sourcegrab_pattern_name,
+            entity_id, entity_type, entity_name, create_time,
+            start_time, forecast_time, pre_qrts, power
+        ) values
+        <foreach collection="list" item="item" separator=",">
+            (
+                #{item.dataSourcegrabId}, #{item.dataSourcegrabPatternName},
+                #{item.entityId}, #{item.entityType,jdbcType=BIGINT}, #{item.entityName,jdbcType=VARCHAR}, EXTRACT(EPOCH FROM now())::INTEGER,
+                #{item.startTime}, #{item.forecastTime},
+                #{item.preQrts}, #{item.power,jdbcType=VARCHAR}
+            )
+        </foreach>
+    </insert>
+
+    <!-- 批量修改下发数据(功率数据文件处理器): 按_id更新预测功率 -->
+    <update id="batchUpdateDataSuperShortTermForecastIssued" parameterType="java.util.List">
+        update data_super_short_term_forecast_issued as t
+        set power = v.power
+        from (values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.Id}::bigint, #{item.power,jdbcType=VARCHAR}::varchar)
+        </foreach>
+        ) as v(_id, power)
+        where t._id = v._id
+    </update>
 </mapper>

+ 21 - 0
forecast-backend-server/src/main/resources/mybatis/supershort/DataSuperShortTermForecastReportMapper.xml

@@ -143,4 +143,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             (#{item.dataSourcegrabId}, #{item.dataSourcegrabPatternName}, #{item.entityId}, #{item.entityType}, #{item.entityName}, #{item.createTimeEpoch}, #{item.startTime}, #{item.forecastTime}, #{item.preQrts}, #{item.power}, #{item.batchNo})
         </foreach>
     </insert>
+
+    <!-- 按entity_id与start_time精确匹配查询场站上报数据(仅batch_no为空的行, 供upsert查重) -->
+    <select id="selectByEntityAndStartTime" parameterType="DataSuperShortTermForecastReport" resultMap="DataSuperShortTermForecastReportResult">
+        <include refid="selectDataSuperShortTermForecastReportVo"/>
+        where entity_id = #{entityId}
+          and start_time = #{startTime}
+          and batch_no is null
+        order by forecast_time asc
+    </select>
+
+    <!-- 批量修改上报数据(功率数据文件处理器): 按_id更新预测功率, 仅作用于batch_no为空的行 -->
+    <update id="batchUpdateDataSuperShortTermForecastReport" parameterType="java.util.List">
+        update data_super_short_term_forecast_report as t
+        set power = v.power
+        from (values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.Id}::bigint, #{item.power,jdbcType=VARCHAR}::varchar)
+        </foreach>
+        ) as v(_id, power)
+        where t._id = v._id and t.batch_no is null
+    </update>
 </mapper>