T1H修改

This commit is contained in:
hekaiyu 2025-12-10 18:03:12 +08:00
parent 732d912314
commit 206165fb4e
5 changed files with 87 additions and 46 deletions

View File

@ -86,4 +86,10 @@ public class WeatherData implements Serializable {
*/ */
@TableField(value = "share_index") @TableField(value = "share_index")
private Integer shareIndex; private Integer shareIndex;
/**
* 日期批次
*/
@TableField(value = "time_batch")
private String timeBatch;
} }

View File

@ -1,5 +1,6 @@
package org.jeecg.controller; package org.jeecg.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -8,6 +9,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.enums.WeatherDataSourceEnum;
import org.jeecg.common.constant.enums.WeatherFileSuffixEnum; import org.jeecg.common.constant.enums.WeatherFileSuffixEnum;
import org.jeecg.common.system.query.PageRequest; import org.jeecg.common.system.query.PageRequest;
import org.jeecg.job.DownloadT1hJob; import org.jeecg.job.DownloadT1hJob;
@ -22,6 +24,7 @@ import org.springframework.web.bind.annotation.*;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Slf4j @Slf4j
@Validated @Validated
@ -68,6 +71,24 @@ public class WeatherDataController {
return Result.ok(resultVo); return Result.ok(resultVo);
} }
} }
/**
* 查询批次列表
* @return
*/
@AutoLog(value = "查询批次列表")
@Operation(summary = "查询批次列表")
@GetMapping(value = "getTimeBatch")
public Result<?> getTimeBatch() {
List<String> timeBatchList = weatherDataService
.list(new LambdaQueryWrapper<WeatherData>()
.select(WeatherData::getTimeBatch) // 只查询需要的字段
.eq(WeatherData::getDataSource, WeatherDataSourceEnum.T1H.getKey()))
.stream()
.map(WeatherData::getTimeBatch)
.distinct()
.collect(Collectors.toList());
return Result.OK(timeBatchList);
}
/** /**
* 气象预测 * 气象预测
@ -78,9 +99,10 @@ public class WeatherDataController {
@GetMapping(value = "getWeatherData") @GetMapping(value = "getWeatherData")
public Result<?> getWeatherData(Integer dataType, public Result<?> getWeatherData(Integer dataType,
Integer weatherType, Integer weatherType,
String timeBatch,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
int hour) { int hour) {
return Result.OK(weatherDataService.getWeatherData(dataType, weatherType, startTime, hour)); return Result.OK(weatherDataService.getWeatherData(dataType, weatherType, timeBatch, startTime, hour));
} }
/** /**
@ -90,8 +112,8 @@ public class WeatherDataController {
@AutoLog(value = "气象预测-气象预览") @AutoLog(value = "气象预测-气象预览")
@Operation(summary = "气象预测-气象预览") @Operation(summary = "气象预测-气象预览")
@GetMapping(value = "getWeatherDataPreview") @GetMapping(value = "getWeatherDataPreview")
public Result<?> getWeatherDataPreview(String weatherId,Integer weatherType) { public Result<?> getWeatherDataPreview(String weatherId,Integer weatherType, String timeBatch) {
return Result.OK(weatherDataService.getWeatherDataPreview(weatherId, weatherType)); return Result.OK(weatherDataService.getWeatherDataPreview(weatherId, weatherType,timeBatch));
} }
/** /**
@ -102,11 +124,12 @@ public class WeatherDataController {
@Operation(summary = "气象预测-气象折线图") @Operation(summary = "气象预测-气象折线图")
@GetMapping(value = "getDataLine") @GetMapping(value = "getDataLine")
public Result<?> getDataLine(Integer dataType, public Result<?> getDataLine(Integer dataType,
String timeBatch,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
double longitude, double longitude,
double latitude) { double latitude) {
return Result.OK(weatherDataService.getDataLine(dataType,startTime,endTime,longitude,latitude)); return Result.OK(weatherDataService.getDataLine(dataType,timeBatch,startTime,endTime,longitude,latitude));
} }
/** /**
@ -117,11 +140,12 @@ public class WeatherDataController {
@Operation(summary = "气象预测-风场玫瑰图") @Operation(summary = "气象预测-风场玫瑰图")
@GetMapping(value = "getWindRose") @GetMapping(value = "getWindRose")
public Result<?> getWindRose(Integer dataType, public Result<?> getWindRose(Integer dataType,
String timeBatch,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
double longitude, double longitude,
double latitude) { double latitude) {
return Result.OK(weatherDataService.getWindRose(dataType,startTime,endTime,longitude,latitude)); return Result.OK(weatherDataService.getWindRose(dataType,timeBatch,startTime,endTime,longitude,latitude));
} }
@AutoLog(value = "删除气象数据") @AutoLog(value = "删除气象数据")

View File

@ -51,9 +51,9 @@ public class DownloadT1hJob {
// 第二阶段合并文件 // 第二阶段合并文件
mergeT1hFiles(baseTime); mergeT1hFiles(baseTime);
// 合并后删除原始文件 // 合并后删除原始文件
Arrays.stream(new File(getFullPath(t1hDownloadProperties.getT1hPath())).listFiles()).filter(File::isFile).forEach(File::delete); Arrays.stream(new File(getFullPath(t1hDownloadProperties.getT1hPath(), baseTime)).listFiles()).filter(File::isFile).forEach(File::delete);
// 更新气象文件信息 // 更新气象文件信息
saveWeatherData(); saveWeatherData(baseTime);
log.info("T1H文件下载任务执行完成"); log.info("T1H文件下载任务执行完成");
} catch (Exception e) { } catch (Exception e) {
log.error("T1H文件下载任务执行失败", e); log.error("T1H文件下载任务执行失败", e);
@ -88,8 +88,8 @@ public class DownloadT1hJob {
ProcessBuilder processBuilder = new ProcessBuilder( ProcessBuilder processBuilder = new ProcessBuilder(
"python", "python",
getPythonScriptPath(t1hDownloadProperties.getMergeT1hPy()), getPythonScriptPath(t1hDownloadProperties.getMergeT1hPy()),
"--indir", getFullPath(t1hDownloadProperties.getT1hPath()), "--indir", getFullPath(t1hDownloadProperties.getT1hPath(), baseTime),
"--output_dir", getFullPath(systemStorageProperties.getT1h()), "--output_dir", getFullPath(systemStorageProperties.getT1h(), baseTime),
"--variables", String.join(",", variables), "--variables", String.join(",", variables),
"--forecast_times", String.join(",", forecastTimes), "--forecast_times", String.join(",", forecastTimes),
"--base_date", baseTime "--base_date", baseTime
@ -98,7 +98,7 @@ public class DownloadT1hJob {
ExecutePyUtils.executePythonProcess(processBuilder, "文件合并"); ExecutePyUtils.executePythonProcess(processBuilder, "文件合并");
} }
private void saveWeatherData(){ private void saveWeatherData(String baseTime){
//删除一个月前的文件 //删除一个月前的文件
LocalDateTime oneMonthAgo = LocalDateTime.now().minusMonths(1); LocalDateTime oneMonthAgo = LocalDateTime.now().minusMonths(1);
List<WeatherData> weatherDatas = weatherDataService.list(new LambdaQueryWrapper<WeatherData>().lt(WeatherData::getDataStartTime, oneMonthAgo)); List<WeatherData> weatherDatas = weatherDataService.list(new LambdaQueryWrapper<WeatherData>().lt(WeatherData::getDataStartTime, oneMonthAgo));
@ -114,7 +114,7 @@ public class DownloadT1hJob {
// 删除数据库记录 // 删除数据库记录
weatherDataService.remove(new LambdaQueryWrapper<WeatherData>().eq(WeatherData::getDataSource, WeatherDataSourceEnum.T1H.getKey())); weatherDataService.remove(new LambdaQueryWrapper<WeatherData>().eq(WeatherData::getDataSource, WeatherDataSourceEnum.T1H.getKey()));
// 读取目录文件信息 // 读取目录文件信息
List<WeatherData> weatherFileInfos = readFolderFiles(getFullPath(systemStorageProperties.getT1h())); List<WeatherData> weatherFileInfos = readFolderFiles(baseTime);
//保存文件信息 //保存文件信息
weatherDataService.saveBatch(weatherFileInfos); weatherDataService.saveBatch(weatherFileInfos);
} }
@ -140,7 +140,7 @@ public class DownloadT1hJob {
getPythonScriptPath(t1hDownloadProperties.getDownloadT1hPy()), getPythonScriptPath(t1hDownloadProperties.getDownloadT1hPy()),
"--base-time", baseTime, "--base-time", baseTime,
"--element", element, "--element", element,
"--output-dir", getFullPath(t1hDownloadProperties.getT1hPath()), "--output-dir", getFullPath(t1hDownloadProperties.getT1hPath(), baseTime),
"--forecast-hours", forecastHours, "--forecast-hours", forecastHours,
"--auth-token", t1hDownloadProperties.getT1hKey(), "--auth-token", t1hDownloadProperties.getT1hKey(),
"--data-type", t1hDownloadProperties.getDataType() "--data-type", t1hDownloadProperties.getDataType()
@ -164,18 +164,19 @@ public class DownloadT1hJob {
return forecastTimes; return forecastTimes;
} }
public List<WeatherData> readFolderFiles(String folderPath) { public List<WeatherData> readFolderFiles(String baseTime) {
String folderPath = getFullPath(systemStorageProperties.getT1h(), baseTime);
try (Stream<Path> paths = Files.list(Paths.get(folderPath))) { try (Stream<Path> paths = Files.list(Paths.get(folderPath))) {
return paths.filter(Files::isRegularFile) return paths.filter(Files::isRegularFile)
.map(Path::toFile) .map(Path::toFile)
.map(this::extractFileInfo) .map(file -> extractFileInfo(file, baseTime))
.collect(Collectors.toList()); .collect(Collectors.toList());
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException("读取文件夹失败: " + folderPath, e); throw new RuntimeException("读取文件夹失败: " + folderPath, e);
} }
} }
private WeatherData extractFileInfo(File file) { private WeatherData extractFileInfo(File file, String baseTime) {
WeatherData data = new WeatherData(); WeatherData data = new WeatherData();
data.setFileName(file.getName()); data.setFileName(file.getName());
data.setFileSize((double) file.length() / 1024 / 1024); // MB data.setFileSize((double) file.length() / 1024 / 1024); // MB
@ -186,6 +187,7 @@ public class DownloadT1hJob {
data.setCreateTime(new Date()); data.setCreateTime(new Date());
data.setMd5Value(calculateMD5(file.getAbsolutePath())); data.setMd5Value(calculateMD5(file.getAbsolutePath()));
data.setShareTotal(1); data.setShareTotal(1);
data.setTimeBatch(baseTime);
return data; return data;
} }
@ -218,8 +220,8 @@ public class DownloadT1hJob {
/** /**
* 获取完整路径 * 获取完整路径
*/ */
private String getFullPath(String relativePath) { private String getFullPath(String relativePath, String baseTime) {
return systemStorageProperties.getRootPath() + File.separator + relativePath; return systemStorageProperties.getRootPath() + File.separator + relativePath + File.separator + baseTime;
} }
/** /**

View File

@ -11,10 +11,10 @@ import java.util.List;
public interface WeatherDataService extends IService<WeatherData> { public interface WeatherDataService extends IService<WeatherData> {
WeatherResultVO getWeatherData(Integer dataType, Integer weatherType, LocalDateTime startTime, int hour); WeatherResultVO getWeatherData(Integer dataType, Integer weatherType, String timeBatch, LocalDateTime startTime, int hour);
WeatherResultVO getWeatherDataPreview(String weatherId, Integer weatherType); WeatherResultVO getWeatherDataPreview(String weatherId, Integer weatherType, String timeBatch);
WindDataLineVO getDataLine(Integer dataType, LocalDateTime startTime, LocalDateTime endTime, double longitude, double latitude); WindDataLineVO getDataLine(Integer dataType, String timeBatch, LocalDateTime startTime, LocalDateTime endTime, double longitude, double latitude);
List<WindRoseData> getWindRose(Integer dataType, LocalDateTime startTime, LocalDateTime endTime,double longitude, double latitude); List<WindRoseData> getWindRose(Integer dataType, String timeBatch, LocalDateTime startTime, LocalDateTime endTime,double longitude, double latitude);
/** /**
* 分页查询气象数据 * 分页查询气象数据

View File

@ -71,22 +71,22 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
* @return 天气数据列表 * @return 天气数据列表
*/ */
@Override @Override
public WeatherResultVO getWeatherData(Integer dataType, Integer weatherType, LocalDateTime startTime, int hour) { public WeatherResultVO getWeatherData(Integer dataType, Integer weatherType, String timeBatch, LocalDateTime startTime, int hour) {
validateInputParams(weatherType, startTime, hour); validateInputParams(weatherType, startTime, hour);
LocalDateTime targetTime = startTime.plusHours(hour); LocalDateTime targetTime = startTime.plusHours(hour);
try { try {
if (WeatherDataSourceEnum.PANGU.getKey() == dataType) { if (WeatherDataSourceEnum.PANGU.getKey() == dataType) {
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.PANGU); return processWeatherData(weatherType, null, targetTime, WeatherDataSourceEnum.PANGU);
} else if (WeatherDataSourceEnum.CRA40.getKey() == dataType){ } else if (WeatherDataSourceEnum.CRA40.getKey() == dataType){
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.CRA40); return processWeatherData(weatherType, null, targetTime, WeatherDataSourceEnum.CRA40);
} else if (WeatherDataSourceEnum.NCEP.getKey() == dataType){ } else if (WeatherDataSourceEnum.NCEP.getKey() == dataType){
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.NCEP); return processWeatherData(weatherType, null, targetTime, WeatherDataSourceEnum.NCEP);
} else if (WeatherDataSourceEnum.FNL.getKey() == dataType){ } else if (WeatherDataSourceEnum.FNL.getKey() == dataType){
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.FNL); return processWeatherData(weatherType,null, targetTime, WeatherDataSourceEnum.FNL);
} else if (WeatherDataSourceEnum.T1H.getKey() == dataType){ } else if (WeatherDataSourceEnum.T1H.getKey() == dataType){
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.T1H); return processWeatherData(weatherType, timeBatch, targetTime, WeatherDataSourceEnum.T1H);
} }
} catch (JeecgBootException e) { } catch (JeecgBootException e) {
throw e; throw e;
@ -104,22 +104,22 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
* @return 天气数据列表 * @return 天气数据列表
*/ */
@Override @Override
public WeatherResultVO getWeatherDataPreview(String weatherId, Integer weatherType) { public WeatherResultVO getWeatherDataPreview(String weatherId, Integer weatherType, String timeBatch) {
Objects.requireNonNull(weatherId, "天气数据ID不能为空"); Objects.requireNonNull(weatherId, "天气数据ID不能为空");
WeatherData weatherData = this.baseMapper.selectById(weatherId); WeatherData weatherData = this.baseMapper.selectById(weatherId);
Integer dataType = weatherData.getDataSource(); Integer dataType = weatherData.getDataSource();
LocalDateTime targetTime = weatherData.getDataStartTime(); LocalDateTime targetTime = weatherData.getDataStartTime();
try { try {
if (WeatherDataSourceEnum.PANGU.getKey() == dataType) { if (WeatherDataSourceEnum.PANGU.getKey() == dataType) {
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.PANGU); return processWeatherData(weatherType, null, targetTime, WeatherDataSourceEnum.PANGU);
} else if (WeatherDataSourceEnum.CRA40.getKey() == dataType){ } else if (WeatherDataSourceEnum.CRA40.getKey() == dataType){
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.CRA40); return processWeatherData(weatherType, null, targetTime, WeatherDataSourceEnum.CRA40);
} else if (WeatherDataSourceEnum.NCEP.getKey() == dataType){ } else if (WeatherDataSourceEnum.NCEP.getKey() == dataType){
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.NCEP); return processWeatherData(weatherType, null, targetTime, WeatherDataSourceEnum.NCEP);
} else if (WeatherDataSourceEnum.FNL.getKey() == dataType){ } else if (WeatherDataSourceEnum.FNL.getKey() == dataType){
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.FNL); return processWeatherData(weatherType, null, targetTime, WeatherDataSourceEnum.FNL);
} else if (WeatherDataSourceEnum.T1H.getKey() == dataType){ } else if (WeatherDataSourceEnum.T1H.getKey() == dataType){
return processWeatherData(weatherType, targetTime, WeatherDataSourceEnum.T1H); return processWeatherData(weatherType, timeBatch, targetTime, WeatherDataSourceEnum.T1H);
} }
} catch (JeecgBootException e) { } catch (JeecgBootException e) {
throw e; throw e;
@ -140,15 +140,20 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
* @return 天气数据列表 * @return 天气数据列表
*/ */
@Override @Override
public WindDataLineVO getDataLine(Integer dataType, LocalDateTime startTime, LocalDateTime endTime, public WindDataLineVO getDataLine(Integer dataType, String timeBatch, LocalDateTime startTime, LocalDateTime endTime,
double longitude, double latitude) { double longitude, double latitude) {
// 参数校验 // 参数校验
if (startTime == null || endTime == null || startTime.isAfter(endTime)) { if (startTime == null || endTime == null || startTime.isAfter(endTime)) {
throw new IllegalArgumentException("时间参数无效"); throw new IllegalArgumentException("时间参数无效");
} }
List<WeatherData> weatherDataList = weatherDataMapper.selectList(new LambdaQueryWrapper<WeatherData>(). LambdaQueryWrapper<WeatherData> queryWrapper = new LambdaQueryWrapper<>();
between(WeatherData::getDataStartTime, startTime, endTime).eq(WeatherData::getDataSource,dataType)); queryWrapper.between(WeatherData::getDataStartTime, startTime, endTime).eq(WeatherData::getDataSource,dataType);
if(StringUtils.isNotBlank(timeBatch)){
queryWrapper.eq(WeatherData::getTimeBatch, timeBatch);
}
List<WeatherData> weatherDataList = weatherDataMapper.selectList(queryWrapper);
if (weatherDataList == null || weatherDataList.isEmpty()) { if (weatherDataList == null || weatherDataList.isEmpty()) {
throw new IllegalArgumentException("时间范围内没有气象数据"); throw new IllegalArgumentException("时间范围内没有气象数据");
} }
@ -228,19 +233,19 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
} }
@Override @Override
public List<WindRoseData> getWindRose(Integer dataType, LocalDateTime startTime, LocalDateTime endTime, public List<WindRoseData> getWindRose(Integer dataType, String timeBatch, LocalDateTime startTime, LocalDateTime endTime,
double longitude, double latitude) { double longitude, double latitude) {
// 参数校验 // 参数校验
if (startTime == null || endTime == null || startTime.isAfter(endTime)) { if (startTime == null || endTime == null || startTime.isAfter(endTime)) {
throw new IllegalArgumentException("时间参数无效"); throw new IllegalArgumentException("时间参数无效");
} }
List<WeatherData> weatherDataList = weatherDataMapper.selectList( LambdaQueryWrapper<WeatherData> queryWrapper = new LambdaQueryWrapper<>();
new LambdaQueryWrapper<WeatherData>() queryWrapper.between(WeatherData::getDataStartTime, startTime, endTime).eq(WeatherData::getDataSource, dataType);
.between(WeatherData::getDataStartTime, startTime, endTime) if(StringUtils.isNotBlank(timeBatch)){
.eq(WeatherData::getDataSource, dataType) queryWrapper.eq(WeatherData::getTimeBatch, timeBatch);
); }
List<WeatherData> weatherDataList = weatherDataMapper.selectList(queryWrapper);
if (weatherDataList == null || weatherDataList.isEmpty()) { if (weatherDataList == null || weatherDataList.isEmpty()) {
throw new IllegalArgumentException("时间范围内没有气象数据"); throw new IllegalArgumentException("时间范围内没有气象数据");
} }
@ -718,9 +723,13 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
/** /**
* 处理天气数据 * 处理天气数据
*/ */
private WeatherResultVO processWeatherData(Integer weatherType, LocalDateTime targetTime, WeatherDataSourceEnum dataTypeEnum) { private WeatherResultVO processWeatherData(Integer weatherType, String timeBatch, LocalDateTime targetTime, WeatherDataSourceEnum dataTypeEnum) {
List<WeatherData> weatherDataList = weatherDataMapper.selectList(new LambdaQueryWrapper<WeatherData>(). LambdaQueryWrapper<WeatherData> queryWrapper = new LambdaQueryWrapper<>();
eq(WeatherData::getDataStartTime, targetTime).eq(WeatherData::getDataSource,dataTypeEnum.getKey())); queryWrapper.eq(WeatherData::getDataStartTime, targetTime).eq(WeatherData::getDataSource,dataTypeEnum.getKey());
if(StringUtils.isNotBlank(timeBatch)){
queryWrapper.eq(WeatherData::getTimeBatch, timeBatch);
}
List<WeatherData> weatherDataList = weatherDataMapper.selectList(queryWrapper);
WeatherResultVO weatherResultVO = new WeatherResultVO(); WeatherResultVO weatherResultVO = new WeatherResultVO();
String filePath = getWeatherFilePath(weatherDataList, targetTime); String filePath = getWeatherFilePath(weatherDataList, targetTime);
validateFile(filePath); validateFile(filePath);