Compare commits

...

2 Commits

Author SHA1 Message Date
hekaiyu
457da7d6aa Merge remote-tracking branch 'origin/master' 2025-11-07 16:03:08 +08:00
hekaiyu
b5885b3f81 wrf调用
气象查询路径查询数据库
2025-11-06 20:19:06 +08:00
33 changed files with 928 additions and 718 deletions

View File

@ -334,5 +334,16 @@
<artifactId>netcdfAll</artifactId>
<version>${netcdfAll.version}</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<!-- ssh2远程连接 -->
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>build210</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,6 @@
package org.jeecg.common.constant;
public class EventConstants {
public static final String WRF_DIR = "wrf";
}

View File

@ -0,0 +1,38 @@
package org.jeecg.common.constant.enums;
/**
* 预测任务状态说明枚举
*/
public enum EnginStatusEnum {
/**
* 未开始
*/
NOT_STARTED(0),
/**
* 进行中
*/
IN_OPERATION(1),
/**
* 暂停
*/
PAUSED(2),
/**
* 继续运行
*/
RESUMED(3),
/**
* 结束运行
*/
FINISHED(4);
private Integer key;
EnginStatusEnum(Integer key) {
this.key = key;
}
public Integer getKey(){
return this.key;
}
}

View File

@ -24,7 +24,7 @@ public enum WeatherDataSourceEnum {
NCEP(4,"NCEP"),
/**
* T1H
* FNL
*/
FNL(5,"FNL"),

View File

@ -0,0 +1,47 @@
package org.jeecg.common.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "event")
public class EventServerProperties {
/**
* 服务器ip
*/
private String ip;
/**
* 服务器用户名
*/
private String username;
/**
* 服务器密码
*/
private String password;
/**
* 服务器端口
*/
private int port;
/**
* 根目录
*/
private String baseHome;
/**
* 结果文件存放根目录
*/
private String resultFilePrefix;
/**
* 气象文件存放目录
*/
private String pythonPath;
}

View File

@ -0,0 +1,242 @@
package org.jeecg.common.util;
/**
* Created by hpp on 2017/6/5.
*/
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* 远程执行linux的shell script
* @author Ickes
* @author2 hpp
* @since V0.2
*/
public class RemoteExecuteCommand {
//字符编码默认是utf-8
private static String DEFAULTCHART="UTF-8";
private static Connection conn;
private String ip;
private String userName;
private String userPwd;
public RemoteExecuteCommand(String ip, String userName, String userPwd) {
this.ip = ip;
this.userName = userName;
this.userPwd = userPwd;
}
public RemoteExecuteCommand() {
}
/**
* 远程登录linux的主机
* @author Ickes
* @since V0.1
* @return
* 登录成功返回true否则返回false
*/
public Boolean login(){
boolean flg=false;
try {
conn = new Connection(ip);
conn.connect();//连接
flg=conn.authenticateWithPassword(userName, userPwd);//认证
if (flg){
System.out.println("认证成功!");
}
} catch (IOException e) {
e.printStackTrace();
}
return flg;
}
/**
* @author Ickes
* 远程执行shll脚本或者命令
* @param cmd
* 即将执行的命令
* @return
* 命令执行完后返回的结果值
* @since V0.1
*/
public String execute(String cmd){
String result="";
try {
if(login()){
Session session= conn.openSession();//打开一个会话
session.execCommand(cmd);//执行命令
result=processStdout(session.getStdout(),DEFAULTCHART);
//如果为得到标准输出为空说明脚本执行出错了
if(StringUtils.isBlank(result)){
result=processStdout(session.getStderr(),DEFAULTCHART);
}
conn.close();
session.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* @author Ickes
* 远程执行shll脚本或者命令
* @param cmd
* 即将执行的命令
* @return
* 命令执行成功后返回的结果值如果命令执行失败返回空字符串不是null
* @since V0.1
*/
public String executeSuccess(String cmd){
String result="";
try {
if(login()){
Session session= conn.openSession();//打开一个会话
session.execCommand(cmd);//执行命令
result=processStdout(session.getStdout(),DEFAULTCHART);
conn.close();
session.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 解析脚本执行返回的结果集
* @author Ickes
* @param in 输入流对象
* @param charset 编码
* @since V0.1
* @return
* 以纯文本的格式返回
*/
public static String processStdout(InputStream in, String charset){
InputStream stdout = new StreamGobbler(in);
StringBuffer buffer = new StringBuffer();;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(stdout,charset));
String line=null;
while((line=br.readLine()) != null){
buffer.append(line+"\n");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer.toString();
}
//远程连接并执行多条linux命令
public static List<String> runRemoteLinuxCmd(String linux_ip,String linux_username,String password, List<String> lines) {
System.out.println("runRemoteLinuxCmds");
//执行的命令返回结果
List<String> resultList = new ArrayList<>();
if(lines!=null && lines.size()>0 && StringUtils.isNotBlank(linux_ip) && StringUtils.isNotBlank(linux_username) && StringUtils.isNotBlank(password)){
RemoteExecuteCommand remote = new RemoteExecuteCommand(linux_ip,linux_username,password);
for (String cmd : lines) {
System.out.println("cmdString:" + cmd);
String execute = remote.execute(cmd);
resultList.add(execute);
}
}
return resultList;
}
//远程连接并执行单条linux命令
public static String runRemoteLinuxCmd(String linux_ip,String linux_username,String password, String cmd) {
System.out.println("cmdString:" + cmd);
//执行的命令返回结果
String executeResult = "";
if(StringUtils.isNotBlank(cmd) && StringUtils.isNotBlank(linux_ip) && StringUtils.isNotBlank(linux_username) && StringUtils.isNotBlank(password)){
RemoteExecuteCommand remote = new RemoteExecuteCommand(linux_ip,linux_username,password);
executeResult = remote.execute(cmd);
}
return executeResult;
}
public static void main(String[] args) {
RemoteExecuteCommand rec=new RemoteExecuteCommand("172.21.70.56", "oracle","123!@#qwe");
//执行命令
try {
if(rec.login()){
System.out.println("=====第一个步骤=====");
Session session= conn.openSession();//打开一个会话
//TODO:多条命令
session.execCommand("/usr/bin/gmt --version");//执行命令
String result=processStdout(session.getStdout(),DEFAULTCHART);
//如果为得到标准输出为空说明脚本执行出错了
if(StringUtils.isBlank(result)){
System.out.println("脚本出错");
result=processStdout(session.getStderr(),DEFAULTCHART);
}
System.out.println(result);
session.close();
// System.out.println("=====第二个步骤=====");
// Session session2= conn.openSession();//打开一个会话
// //TODO:多条命令
// session2.execCommand("cd /home/ubuntu/Desktop/music_rec/user_sim/result;cat xyy_result_m10d.json");//执行命令
// String result2=processStdout(session2.getStdout(),DEFAULTCHART);
// //如果为得到标准输出为空说明脚本执行出错了
// if(StringUtils.isBlank(result2)){
// System.out.println("脚本出错");
// result2=processStdout(session2.getStderr(),DEFAULTCHART);
// }
// System.out.println(result2);
// session2.close();
conn.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void setCharset(String charset) {
DEFAULTCHART = charset;
}
public Connection getConn() {
return conn;
}
public void setConn(Connection conn) {
this.conn = conn;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}

View File

@ -41,6 +41,8 @@ public class Cmaq implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
private String enginId;
private String startDate;
private String endDate;
@ -123,8 +125,6 @@ public class Cmaq implements Serializable {
private String wrfLcRefLat;
private String engineeringId;
private int temType;
private int sceneType;

View File

@ -1,73 +0,0 @@
package org.jeecg.modules.base.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: 核设施配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@Data
@TableName("stas_config_facility")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class ConfigFacility implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
/**创建人*/
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**更新人*/
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**工程ID*/
@Excel(name = "工程ID", width = 15)
private String engineeringId;
/**设施地区*/
@Excel(name = "设施地区", width = 15)
private String facilityArea;
/**设施地区*/
@Excel(name = "设施名称", width = 15)
private String facilityName;
/**设施地区*/
@Excel(name = "设施机组", width = 15)
private String unit;
/**设施ID*/
@Excel(name = "设施ID", width = 15)
private String facilityId;
/**经度*/
@Excel(name = "经度", width = 15)
private Double lon;
/**纬度*/
@Excel(name = "纬度", width = 15)
private Double lat;
/**事件时间*/
@Excel(name = "事件时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date eventTime;
/**事故类型*/
@Excel(name = "事故类型", width = 15)
private String eventType;
}

View File

@ -1,70 +0,0 @@
package org.jeecg.modules.base.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: 核爆配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@Data
@TableName("stas_config_nucleus")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class ConfigNucleus implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
/**创建人*/
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**更新人*/
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**工程ID*/
@Excel(name = "工程ID", width = 15)
private String engineeringId;
/**城市id*/
@Excel(name = "城市id", width = 15)
private String cityId;
/**经度*/
@Excel(name = "经度", width = 15)
private Double lon;
/**纬度*/
@Excel(name = "纬度", width = 15)
private Double lat;
/**事件时间*/
@Excel(name = "事件时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date eventTime;
/**武器ID*/
@Excel(name = "武器ID", width = 15)
private String weaponId;
/**高度*/
@Excel(name = "高度", width = 15)
private Double height;
/**DL*/
@Excel(name = "DL", width = 15)
private Double dl;
}

View File

@ -28,13 +28,13 @@ public class Engineering {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 工程状态(1:未运行2:正在运行3:暂停4:继续运行5:结束运行)
* 工程状态(0:未运行1:正在运行2:暂停3:继续运行4:结束运行)
* */
private int enginStatus;
private Integer enginStatus;
/**工程名称*/
private String engineeringName;
/**场景类型*/
private Integer sceneType;
/**模式选择*/
private Integer modeType;
/**工程备注*/
private String remark;
}

View File

@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
@ -40,89 +41,27 @@ public class Wrf implements Serializable {
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**事件Id*/
private String enginId;
/**事件开始时间*/
private String startTime;
/**事件结束时间*/
private String endTime;
/**事件模拟小时数*/
private String analogTime;
/**事件模拟天数*/
private String runDays;
/**事件类型*/
private Integer sceneType;
/**事件天气类型*/
private Integer weatherDataType;
private String runHours;
private String runMinutes;
private Double refLat;
private Double refLon;
private Double truelat1;
private Double truelat2;
private Double standLon;
private String runSeconds;
private String intervalSeconds;
private String historyInterval;
private String framesPerOutfile;
private String timeStep;
private String we;
private String sn;
private String vert;
private String dx;
private String dy;
private String physicsSuite;
private String mapProj;
private String refLat;
private String refLon;
private String truelat1;
private String truelat2;
private String standLon;
private String lat1;
private String lon1;
private String lat2;
private String lon2;
private String engineeringId;
private int xIndex;
private int yIndex;
private int temType;
private int sceneType;
private int modeType;
private String modeSchemeName;
private String filePath;
private String wrfCore;
private Integer maxDom;
private String parentGridRatio;
private String parentStartI;
private String parentStartJ;
private String geogDataRes;
private String timeStamp;
}

View File

@ -1,16 +0,0 @@
package org.jeecg.modules.base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jeecg.modules.base.entity.ConfigFacility;
/**
* @Description: 核设施配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@Mapper
public interface ConfigFacilityMapper extends BaseMapper<ConfigFacility> {
}

View File

@ -1,16 +0,0 @@
package org.jeecg.modules.base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jeecg.modules.base.entity.ConfigNucleus;
/**
* @Description: 核爆配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@Mapper
public interface ConfigNucleusMapper extends BaseMapper<ConfigNucleus> {
}

View File

@ -1,128 +0,0 @@
package org.jeecg.configFacility.controller;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.configFacility.service.ConfigFacilityService;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.base.entity.ConfigFacility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.jeecg.common.aspect.annotation.AutoLog;
/**
* @Description: 核设施配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@RestController
@RequestMapping("/configFacility")
@Slf4j
public class ConfigFacilityController extends JeecgController<ConfigFacility, ConfigFacilityService> {
@Autowired
private ConfigFacilityService configFacilityService;
/**
* 分页列表查询
*
* @param ConfigFacility
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@Operation(summary = "核设施配置表-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<ConfigFacility>> queryPageList(ConfigFacility ConfigFacility,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10000") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<ConfigFacility> queryWrapper = QueryGenerator.initQueryWrapper(ConfigFacility, req.getParameterMap());
Page<ConfigFacility> page = new Page<ConfigFacility>(pageNo, pageSize);
IPage<ConfigFacility> pageList = configFacilityService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param ConfigFacility
* @return
*/
@AutoLog(value = "核设施配置表-添加")
@Operation(summary = "核设施配置表-添加")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody ConfigFacility ConfigFacility) {
configFacilityService.save(ConfigFacility);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param ConfigFacility
* @return
*/
@AutoLog(value = "核设施配置表-编辑")
@Operation(summary = "核设施配置表-编辑")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody ConfigFacility ConfigFacility) {
configFacilityService.updateById(ConfigFacility);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "核设施配置表-通过id删除")
@Operation(summary = "核设施配置表-通过id删除")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
configFacilityService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "核设施配置表-批量删除")
@Operation(summary = "核设施配置表-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.configFacilityService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
@Operation(summary = "核设施配置表-通过id查询")
@GetMapping(value = "/queryById")
public Result<ConfigFacility> queryById(@RequestParam(name="id",required=true) String id) {
ConfigFacility ConfigFacility = configFacilityService.getById(id);
if(ConfigFacility==null) {
return Result.error("未找到对应数据");
}
return Result.OK(ConfigFacility);
}
}

View File

@ -1,14 +0,0 @@
package org.jeecg.configFacility.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.base.entity.ConfigFacility;
/**
* @Description: 核设施配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
public interface ConfigFacilityService extends IService<ConfigFacility> {
}

View File

@ -1,19 +0,0 @@
package org.jeecg.configFacility.service.impl;
import org.jeecg.configFacility.service.ConfigFacilityService;
import org.jeecg.modules.base.entity.ConfigFacility;
import org.jeecg.modules.base.mapper.ConfigFacilityMapper;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 核设施配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@Service
public class ConfigFacilityServiceImpl extends ServiceImpl<ConfigFacilityMapper, ConfigFacility> implements ConfigFacilityService {
}

View File

@ -1,130 +0,0 @@
package org.jeecg.configNucleus.controller;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import io.swagger.v3.oas.annotations.Operation;
import org.jeecg.configNucleus.service.ConfigNucleusService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.base.entity.ConfigNucleus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.jeecg.common.aspect.annotation.AutoLog;
/**
* @Description: 核爆配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@RestController
@RequestMapping("/configNucleus")
@Slf4j
public class ConfigNucleusController extends JeecgController<ConfigNucleus, ConfigNucleusService> {
@Autowired
private ConfigNucleusService bizConfigNucleusService;
/**
* 分页列表查询
*
* @param bizConfigNucleus
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "核爆配置表-分页列表查询")
@Operation(summary = "核爆配置表-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<ConfigNucleus>> queryPageList(ConfigNucleus bizConfigNucleus,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10000") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<ConfigNucleus> queryWrapper = QueryGenerator.initQueryWrapper(bizConfigNucleus, req.getParameterMap());
Page<ConfigNucleus> page = new Page<ConfigNucleus>(pageNo, pageSize);
IPage<ConfigNucleus> pageList = bizConfigNucleusService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param bizConfigNucleus
* @return
*/
@AutoLog(value = "核爆配置表-添加")
@Operation(summary = "核爆配置表-添加")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody ConfigNucleus bizConfigNucleus) {
bizConfigNucleusService.save(bizConfigNucleus);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param bizConfigNucleus
* @return
*/
@AutoLog(value = "核爆配置表-编辑")
@Operation(summary = "核爆配置表-编辑")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody ConfigNucleus bizConfigNucleus) {
bizConfigNucleusService.updateById(bizConfigNucleus);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "核爆配置表-通过id删除")
@Operation(summary = "核爆配置表-通过id删除")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
bizConfigNucleusService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "核爆配置表-批量删除")
@Operation(summary = "核爆配置表-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.bizConfigNucleusService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "核爆配置表-通过id查询")
@Operation(summary = "核爆配置表-通过id查询")
@GetMapping(value = "/queryById")
public Result<ConfigNucleus> queryById(@RequestParam(name="id",required=true) String id) {
ConfigNucleus bizConfigNucleus = bizConfigNucleusService.getById(id);
if(bizConfigNucleus==null) {
return Result.error("未找到对应数据");
}
return Result.OK(bizConfigNucleus);
}
}

View File

@ -1,14 +0,0 @@
package org.jeecg.configNucleus.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.base.entity.ConfigNucleus;
/**
* @Description: 核爆配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
public interface ConfigNucleusService extends IService<ConfigNucleus> {
}

View File

@ -1,19 +0,0 @@
package org.jeecg.configNucleus.service.impl;
import org.jeecg.configNucleus.service.ConfigNucleusService;
import org.jeecg.modules.base.entity.ConfigNucleus;
import org.jeecg.modules.base.mapper.ConfigNucleusMapper;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 核爆配置表
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@Service
public class ConfigNucleusServiceImpl extends ServiceImpl<ConfigNucleusMapper, ConfigNucleus> implements ConfigNucleusService {
}

View File

@ -50,7 +50,7 @@ public class DiffusionDataServiceImpl implements DiffusionDataService {
@Override
public DiffusionResultVO getDiffusionResult(String enginId, int hour, int layer) {
Engineering engineering = engineeringMapper.selectById(enginId);
Wrf wrf = wrfMapper.selectOne(new LambdaQueryWrapper<Wrf>().eq(Wrf::getEngineeringId,enginId));
Wrf wrf = wrfMapper.selectOne(new LambdaQueryWrapper<Wrf>().eq(Wrf::getEnginId,enginId));
String wrfFilePath = baseAPIService.buildEngineeringFilePath(diffusionProperties.getWrfPath() ,engineering.getCreateBy(), engineering.getEngineeringName());
String cmaqFilePath = baseAPIService.buildEngineeringFilePath(diffusionProperties.getWrfPath() ,engineering.getCreateBy(), engineering.getEngineeringName());

View File

@ -1,15 +1,22 @@
package org.jeecg.engineering.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.enums.EnginStatusEnum;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.engineering.service.EngineeringService;
import org.jeecg.modules.base.entity.Engineering;
import org.jeecg.modules.base.entity.StasTaskConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -31,21 +38,19 @@ public class EngineeringController {
@AutoLog(value = "查询工程")
@Operation(summary = "查询工程")
@GetMapping(value = "/list")
public Result<List<Engineering>> list(Engineering engineering) {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
LambdaQueryWrapper<Engineering> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if(null != engineering){
if(StringUtils.isNotBlank(engineering.getEngineeringName())){
lambdaQueryWrapper.like(Engineering::getEngineeringName,engineering.getEngineeringName());
}
if(null != engineering.getCreateTime()){
lambdaQueryWrapper.gt(Engineering::getCreateTime,engineering.getCreateTime());
}
public Result<IPage<Engineering>> list(Engineering engineering,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
String enginName = engineering.getEngineeringName();
engineering.setEngineeringName(null);
QueryWrapper<Engineering> queryWrapper = QueryGenerator.initQueryWrapper(engineering, req.getParameterMap());
if(StringUtils.isNotBlank(enginName)){
queryWrapper.like("engineering_name", enginName);
}
lambdaQueryWrapper.eq(Engineering::getCreateBy,sysUser.getUsername());
lambdaQueryWrapper.orderByDesc(Engineering::getCreateTime);
List<Engineering> bizEngineerings = engineeringService.list(lambdaQueryWrapper);
return Result.OK(bizEngineerings);
Page<Engineering> page = new Page<Engineering>(pageNo, pageSize);
IPage<Engineering> pageList = engineeringService.page(page, queryWrapper);
return Result.OK(pageList);
}
@ -59,22 +64,10 @@ public class EngineeringController {
@Operation(summary = "工程管理-添加")
@PostMapping(value = "/add")
public Result<Engineering> add(@RequestBody Engineering engineering) {
if(engineering == null || StringUtils.isBlank(engineering.getEngineeringName())){
return Result.error("工程名称不能为空!!!");
}
if(null != engineering){
engineering.setId(null);
}
Engineering enginInfo = engineeringService.getOne(new LambdaQueryWrapper<Engineering>().eq(Engineering::getEngineeringName, engineering.getEngineeringName()));
if(enginInfo != null){
return Result.error("新建工程失败,工程名称重复!");
}
engineering.setEnginStatus(1);
engineeringService.validateEngineeringForSave(engineering,true);
engineering.setEnginStatus(EnginStatusEnum.NOT_STARTED.getKey());
engineeringService.save(engineering);
engineeringService.initEngin(engineering);
engineeringService.initParamTem(engineering.getId(),engineering.getSceneType());
engineeringService.initParamTem(engineering);
return Result.OK(engineering);
}
@ -88,6 +81,7 @@ public class EngineeringController {
@Operation(summary = "工程管理-编辑")
@PutMapping(value = "/edit")
public Result<String> edit(@RequestBody Engineering engineering) {
engineeringService.validateEngineeringForSave(engineering,false);
engineeringService.updateById(engineering);
return Result.OK("编辑成功!");
}
@ -111,18 +105,4 @@ public class EngineeringController {
return Result.OK("删除成功!");
}
/**
* 修改运行状态
*
* @param engineering
* @return
*/
@AutoLog(value = "工程管理-修改运行状态")
@Operation(summary = "工程管理-修改运行状态")
@PutMapping(value = "/updateRunStatus")
public Result<String> updateRunStatus(@RequestBody Engineering engineering) {
engineeringService.updateById(engineering);
return Result.OK("修改运行状态成功!");
}
}

View File

@ -3,23 +3,25 @@ package org.jeecg.engineering.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.base.entity.Engineering;
import org.jeecg.runProcess.VO.RunProcessParamVO;
import java.util.List;
import java.util.Map;
public interface EngineeringService extends IService<Engineering> {
/**
* 初始化工程参数配置信息
* 初始化模板配置信息
* @param engineering
*/
void initEngin(Engineering engineering);
void initParamTem(Engineering engineering);
/**
* 初始化模板配置信息
* @param enginId
* @param sceneType
* 工程保存前的统一校验
* @param engineering 工程对象
* @param isAdd 是否为新增操作
*/
void initParamTem(String enginId,Integer sceneType);
void validateEngineeringForSave(Engineering engineering, boolean isAdd);
/**
* 级联删除工程
@ -27,5 +29,11 @@ public interface EngineeringService extends IService<Engineering> {
*/
void deleteEngin(String engId);
/**
* 初始化运行目录
* @param engineering
*/
void initDir(Engineering engineering);
}

View File

@ -1,71 +1,77 @@
package org.jeecg.engineering.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.properties.EventServerProperties;
import org.jeecg.common.util.RemoteExecuteCommand;
import org.jeecg.engineering.service.EngineeringService;
import org.jeecg.modules.base.entity.*;
import org.jeecg.modules.base.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.jeecg.runProcess.VO.RunProcessParamVO;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.io.File;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class EngineeringServiceImpl extends ServiceImpl<EngineeringMapper, Engineering> implements EngineeringService {
@Autowired
private WrfMapper wrfMapper;
@Autowired
private CmaqMapper cmaqMapper;
@Autowired
private ConfigFacilityMapper configFacilityMapper;
@Autowired
private ConfigNucleusMapper configNucleusMapper;
private final WrfMapper wrfMapper;
private final CmaqMapper cmaqMapper;
private final EventServerProperties eventServerProperties;
private final EngineeringMapper engineeringMapper;
@Override
public void initParamTem(String enginId,Integer sceneType){
Engineering bizEngineering = this.baseMapper.selectById(enginId);
StringBuffer sb = new StringBuffer();
wrfMapper.delete(new LambdaQueryWrapper<Wrf>().eq(Wrf::getEngineeringId,enginId));
cmaqMapper.delete(new LambdaQueryWrapper<Cmaq>().eq(Cmaq::getEngineeringId,enginId));
Wrf bizWrf = wrfMapper.selectOne(new LambdaQueryWrapper<Wrf>().eq(Wrf::getTemType, 0).eq(Wrf::getSceneType,sceneType));
bizWrf.setId(null);
bizWrf.setEngineeringId(enginId);
bizWrf.setTemType(1);
bizWrf.setSceneType(sceneType);
wrfMapper.insert(bizWrf);
Cmaq bizCmaq = cmaqMapper.selectOne(new LambdaQueryWrapper<Cmaq>().eq(Cmaq::getTemType, 0).eq(Cmaq::getSceneType,sceneType));
bizCmaq.setId(null);
bizCmaq.setEngineeringId(enginId);
bizCmaq.setTemType(1);
bizCmaq.setSceneType(sceneType);
cmaqMapper.insert(bizCmaq);
bizEngineering.setSceneType(sceneType);
this.baseMapper.updateById(bizEngineering);
public void initParamTem(Engineering engineering){
String enginId = engineering.getId();
Integer sceneType = engineering.getSceneType();
wrfMapper.insert(new Wrf().setEnginId(enginId).setSceneType(sceneType));
cmaqMapper.insert(new Cmaq().setEnginId(enginId).setSceneType(sceneType));
}
@Override
public void initEngin(Engineering bizEngineering){
String enginId = bizEngineering.getId();
configFacilityMapper.insert(new ConfigFacility().setEngineeringId(enginId));
configNucleusMapper.insert(new ConfigNucleus().setEngineeringId(enginId));
public void validateEngineeringForSave(Engineering engineering, boolean isAdd) {
if (engineering == null || StringUtils.isBlank(engineering.getEngineeringName())) {
throw new JeecgBootException("工程名称不能为空!!!");
}
LambdaQueryWrapper<Engineering> queryWrapper = new LambdaQueryWrapper<Engineering>()
.eq(Engineering::getEngineeringName, engineering.getEngineeringName());
// 编辑时排除当前工程
if (!isAdd && engineering.getId() != null) {
queryWrapper.ne(Engineering::getId, engineering.getId());
}
Engineering existing = engineeringMapper.selectOne(queryWrapper);
if (existing != null) {
throw new JeecgBootException(isAdd ? "新建工程失败,工程名称重复!" : "编辑工程失败,工程名称重复!");
}
}
@Override
public void deleteEngin(String enginId){
this.baseMapper.deleteById(enginId);
wrfMapper.delete(new LambdaQueryWrapper<Wrf>().eq(Wrf::getEngineeringId,enginId));
cmaqMapper.delete(new LambdaQueryWrapper<Cmaq>().eq(Cmaq::getEngineeringId,enginId));
configFacilityMapper.delete(new LambdaQueryWrapper<ConfigFacility>().eq(ConfigFacility::getEngineeringId,enginId));
configNucleusMapper.delete(new LambdaQueryWrapper<ConfigNucleus>().eq(ConfigNucleus::getEngineeringId,enginId));
wrfMapper.delete(new LambdaQueryWrapper<Wrf>().eq(Wrf::getEnginId,enginId));
cmaqMapper.delete(new LambdaQueryWrapper<Cmaq>().eq(Cmaq::getEnginId,enginId));
}
@Override
public void initDir(Engineering engineering){
String baseHome = eventServerProperties.getBaseHome() + File.separator;
String ip = eventServerProperties.getIp();
String username = eventServerProperties.getUsername();
String password = eventServerProperties.getPassword();
String newAllRunPath = String.format("%s%s/%s/", baseHome, engineering.getCreateBy(),engineering.getEngineeringName());
RemoteExecuteCommand.runRemoteLinuxCmd(ip, username, password, String.format("rm -rf %s",newAllRunPath));
RemoteExecuteCommand.runRemoteLinuxCmd(ip, username, password, String.format("mkdir %s",baseHome + engineering.getCreateBy()));
String runCmd = String.format("cp -rf %sAll_Run %s", baseHome, newAllRunPath);
RemoteExecuteCommand.runRemoteLinuxCmd(ip, username, password, runCmd);
}
}

View File

@ -0,0 +1,17 @@
package org.jeecg.runProcess.VO;
import lombok.Data;
@Data
public class RunProcessParamVO {
private String enginId;
private Integer weatherDataType;
private Integer sceneType;
private String eventTime;
private Integer analogTime;
/**经度*/
private Double refLon;
/**纬度*/
private Double refLat;
}

View File

@ -0,0 +1,9 @@
package org.jeecg.runProcess.VO;
import lombok.Data;
@Data
public class WeatherPathVO {
private String weatherPath;
private String linkGrib;
}

View File

@ -0,0 +1,68 @@
package org.jeecg.runProcess.controller;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.cmaq.service.CmaqService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.engineering.service.EngineeringService;
import org.jeecg.modules.base.entity.Engineering;
import org.jeecg.runProcess.VO.RunProcessParamVO;
import org.jeecg.runProcess.service.RunProcessService;
import org.jeecg.wrf.service.WrfService;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Map;
/**
* @Description: 运行过程
* @Author: jeecg-boot
* @Date: 2023-09-20
* @Version: V1.0
*/
@RestController
@RequestMapping("/runProcess")
@Slf4j
@RequiredArgsConstructor
public class RunProcessController {
private final EngineeringService engineeringService;
private final WrfService wrfService;
private final CmaqService cmaqService;
private final RunProcessService runProcessService;
/**
* 运行wrf所有程序
*
* @param
* @return
*/
@AutoLog(value = "运行过程-运行所有程序")
@Operation(summary = "运行过程-运行所有程序")
@PostMapping(value = "/runAllExe")
public Result<String> runAllExe(@RequestBody RunProcessParamVO paramVO) {
String engineeringId = paramVO.getEnginId();
Integer sceneType = paramVO.getSceneType();
Engineering bizEngineering = engineeringService.getById(engineeringId);
if(bizEngineering == null) {
return Result.error("未找到对应数据");
}
// if(bizEngineering.getEnginStatus() == 2){
// return Result.error("程序正在运行中...");
// }
bizEngineering.setSceneType(sceneType);
bizEngineering.setEnginStatus(2);
engineeringService.updateById(bizEngineering);
engineeringService.initDir(bizEngineering);
wrfService.updateWrfInfo(paramVO);
// bizCmaqService.updateCmaqInfo(engineeringId);
runProcessService.runAllExe(paramVO);
return Result.OK("运行成功!");
}
}

View File

@ -0,0 +1,10 @@
package org.jeecg.runProcess.service;
import org.jeecg.common.api.vo.Result;
import org.jeecg.runProcess.VO.RunProcessParamVO;
import java.util.Map;
public interface RunProcessService {
Result<String> runAllExe(RunProcessParamVO paramVO);
}

View File

@ -0,0 +1,162 @@
package org.jeecg.runProcess.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.jeecg.cmaq.service.CmaqService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.properties.EventServerProperties;
import org.jeecg.engineering.service.EngineeringService;
import org.jeecg.modules.base.entity.Engineering;
import org.jeecg.modules.base.entity.Wrf;
import org.jeecg.runProcess.VO.RunProcessParamVO;
import org.jeecg.runProcess.service.RunProcessService;
import org.jeecg.wrf.service.WrfService;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Service
@RequiredArgsConstructor
public class RunProcessServiceImpl implements RunProcessService {
private final WrfService wrfService;
private final CmaqService cmaqService;
private final EngineeringService engineeringService;
private final EventServerProperties eventServerProperties;
@Override
public Result<String> runAllExe(RunProcessParamVO paramVO){
try{
String engineeringId = paramVO.getEnginId();
Engineering engineering = engineeringService.getById(engineeringId);
Wrf wrf = wrfService.getOne(new LambdaQueryWrapper<Wrf>().eq(Wrf::getEnginId,engineeringId));
//各种路径前缀
String allRunPath = eventServerProperties.getBaseHome() + File.separator + engineering.getCreateBy() + File.separator + engineering.getEngineeringName() + File.separator;
String resultFilePath = eventServerProperties.getBaseHome() + File.separator + eventServerProperties.getResultFilePrefix() +
File.separator + engineering.getCreateBy() + File.separator + engineering.getEngineeringName() + File.separator;
String workDirPath = allRunPath + "workdir/";
String mcipPath = allRunPath + "workdir/MCIP/";
String scriptsPath = allRunPath + "scripts/";
//生成WRF脚本
genWrfRunShell(allRunPath, scriptsPath, wrf);
//运行WRF程序
Result<String> wrfResult = wrfService.runAllWrf(engineeringId,scriptsPath, workDirPath, resultFilePath);
if(!wrfResult.isSuccess()){
return wrfResult;
}
//生成CMAQ脚本
// genMcipRunShell(allRunPath,resultFilePath,mcipPath,wrf);
//运行CMAQ程序
// Result<String> cmaqResult = cmaqService.runAllCmaq(engineering, wrf);
// if(!cmaqResult.isSuccess()){
// return cmaqResult;
// }
// //下载wrf文件
// for (Integer i = 0; i <= sumDay; i++) {
// String newStartTime = DateUtil.format(new Date(startTime.getTime() + oneDaySecs * i), format);
// String ncName = "wrfout_d03_" + newStartTime;
//
// String targetName = "wrfout_d03_" + DateUtil.format(new Date(startTime.getTime() + oneDaySecs * i), "yyyy-MM-dd_HH_mm_ss");
// sftpAPIService.download(allRunPath + "workdir/WRF/",ncName,resultFilePath + targetName);
// }
//
// //下载fnl文件
// String fnlStartTime = DateUtil.format(DateUtil.parse(wrf.getStartTime(), "yyyy-MM-dd_HH:mm:ss"), "yyyyMMdd_HH");
// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HH");
// LocalDateTime dateTime = LocalDateTime.parse(fnlStartTime, formatter);
// for (int t = 0; t < sumDay * 24; t= t+6) {
// // 增加t小时
// LocalDateTime newDateTime = dateTime.plusHours(t);
// String fnlFileName = "fnl_"+ newDateTime.format(formatter) +"_00.grib2";
// sftpAPIService.download(eventServerProperties.getWeatherDataPath() ,fnlFileName,resultFilePath + fnlFileName);
// }
//下载cmaq文件
// for (Integer i = 1; i <= sumDay; i++) {
// String dataString = DateUtil.format(new Date(startTimeSecs + oneDaySecs * i), yyyymdFormat);
// String ncName = "CCTM.CONC.d03."+ dataString;
// String metcr03dName = "METCRO3D_d03_"+ dataString;
// String emisName = "emis_"+ dataString;
// sftpAPIService.download(allRunPath + "workdir/CCTM/",ncName,resultFilePath + ncName);
// sftpAPIService.download(mcipPath,metcr03dName,resultFilePath + metcr03dName);
// sftpAPIService.download(allRunPath + "data/emis/d03/",emisName,resultFilePath + emisName);
// }
}catch (Exception e){
e.printStackTrace();
return Result.error(e.getMessage());
}
return Result.OK("运行成功!");
}
public Result<String> genWrfRunShell(String allRunPath, String scriptsPath, Wrf wrf) {
try {
wrfService.genWpsShell(scriptsPath, "run_wps.sh", wrf);
genProjectShell(allRunPath, scriptsPath, "run_project_wps.sh", wrf.getStartTime(), wrf.getRunDays(),"./run_wps.sh");
genProjectShell(allRunPath, scriptsPath, "run_project_wrf.sh", wrf.getStartTime(), wrf.getRunDays(),"./run_wrf.sh");
} catch (IOException e) {
e.printStackTrace();
return Result.error("生成Txt文件异常");
}
return Result.ok();
}
// public Result<String> genMcipRunShell(String allRunPath ,String resultFilePath, String scriptsPath ,String mcipPath ,Wrf wrf) {
// try {
// genProjectShell(allRunPath,resultFilePath,scriptsPath,"run_project_mcip.sh",wrf.getStartTime(),wrf.getRunDays(),"./run_mcip.sh");
// genProjectShell(allRunPath,resultFilePath,scriptsPath,"run_project_icon.sh",wrf.getStartTime(),wrf.getRunDays(),"./run_icon.sh");
// genProjectShell(allRunPath,resultFilePath,scriptsPath,"run_project_bcon.sh",wrf.getStartTime(),wrf.getRunDays(),"./run_bcon.sh");
// genProjectShell(allRunPath,resultFilePath,scriptsPath,"run_project_cctm.sh",wrf.getStartTime(),wrf.getRunDays(),"./run_cctm.sh");
//
// genPython(allRunPath,resultFilePath,mcipPath,"ocean_base.py","ocean_base_tem.py");
// genPython(allRunPath,resultFilePath,mcipPath,"ocean_update.py","ocean_update_tem.py");
// genPython(allRunPath,resultFilePath,mcipPath,"emis_base_sf6.py","emis_base_sf6_tem.py");
// genPython(allRunPath,resultFilePath,mcipPath,"emis_update_emis_ic.py","emis_update_emis_ic_tem.py");
//
// } catch (IOException e) {
// e.printStackTrace();
// return Result.error("生成Txt文件异常");
// } catch (SftpException e) {
// e.printStackTrace();
// return Result.error("生成脚本文件异常!");
// }
// return Result.ok();
//
// }
private String genProjectShell(String allRunPath, String scriptsPath, String fileName, String startTime, String runDays ,String runShellCmd) throws IOException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
String templateContent = Files.readString(Path.of(scriptsPath, fileName));
String processedContent = templateContent
.replace("#{PROJECT_DIR}", allRunPath.substring(0,allRunPath.length() -1))
.replace("#{YEAR}", String.valueOf(startDateTime.getYear()))
.replace("#{MONTH}", String.format("%02d", startDateTime.getMonthValue()))
.replace("#{DAY}", String.format("%02d", startDateTime.getDayOfMonth()))
.replace("#{RUN_DAYS}", runDays)
.replace("#{runShellCmd}", runShellCmd);
Files.writeString(Path.of(scriptsPath, fileName), processedContent, StandardCharsets.UTF_8);
return fileName;
}
// private String genPython(String allRunPath,String mcipPath,String fileName,String temFileName) throws IOException, SftpException {
//
// String data = new String(readAllBytes(get(eventServerProperties.getCshTemFilePath() + "/" + temFileName)));
// data = data.replace("#{base_path}", allRunPath);
// FileUtil.writeString(data, resultFilePath + fileName, "UTF-8");
// sftpAPIService.sftpUpload(resultFilePath + fileName,mcipPath, fileName);
//
// return fileName;
// }
}

View File

@ -1,5 +1,6 @@
package org.jeecg.wrf.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
@ -24,17 +25,6 @@ public class WrfController extends JeecgController<Wrf, WrfService> {
@Autowired
private WrfService wrfService;
/**
* 通过类型查询模板
*
* @return
*/
@Operation(summary = "通过类型查询模板")
@GetMapping(value = "/getWrfTem")
public Result<Wrf> geWrfTem(Integer sceneType) {
return Result.OK(wrfService.getWrfTem(sceneType));
}
/**
* 编辑
*
@ -49,4 +39,17 @@ public class WrfController extends JeecgController<Wrf, WrfService> {
return Result.OK("编辑成功!");
}
/**
* 编辑
*
* @param enginId
* @return
*/
@AutoLog(value = "编辑")
@Operation(summary = "编辑")
@RequestMapping(value = "/getByEnginId", method = {RequestMethod.GET})
public Result<Wrf> getByEnginId(String enginId) {
return Result.OK(wrfService.getOne(new LambdaQueryWrapper<Wrf>().eq(Wrf::getEnginId,enginId)));
}
}

View File

@ -1,7 +1,11 @@
package org.jeecg.wrf.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.base.entity.Wrf;
import org.jeecg.runProcess.VO.RunProcessParamVO;
import java.io.IOException;
/**
* @Description: wrf
@ -11,6 +15,8 @@ import org.jeecg.modules.base.entity.Wrf;
*/
public interface WrfService extends IService<Wrf> {
Wrf getWrfTem(Integer sceneType);
Result<String> updateWrfInfo(RunProcessParamVO paramVO);
String genWpsShell(String scriptsPath, String fileName, Wrf wrf) throws IOException;
Result<String> runAllWrf(String engId, String scriptsPath, String resultFilePath, String localFilePath) throws IOException;
}

View File

@ -1,13 +1,39 @@
package org.jeecg.wrf.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.EventConstants;
import org.jeecg.common.constant.enums.WeatherDataSourceEnum;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.properties.EventServerProperties;
import org.jeecg.common.properties.SystemStorageProperties;
import org.jeecg.common.util.RemoteExecuteCommand;
import org.jeecg.modules.base.entity.WeatherData;
import org.jeecg.modules.base.entity.Wrf;
import org.jeecg.modules.base.mapper.WeatherDataMapper;
import org.jeecg.modules.base.mapper.WrfMapper;
import org.jeecg.runProcess.VO.RunProcessParamVO;
import org.jeecg.runProcess.VO.WeatherPathVO;
import org.jeecg.wrf.service.WrfService;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import static java.nio.file.Files.readAllBytes;
import static java.nio.file.Paths.get;
/**
* @Description: wrf
* @Author: jeecg-boot
@ -15,19 +41,117 @@ import org.springframework.stereotype.Service;
* @Version: V1.0
*/
@Service
@RequiredArgsConstructor
public class WrfServiceImpl extends ServiceImpl<WrfMapper, Wrf> implements WrfService {
public Wrf getWrfTem(Integer sceneType) {
LambdaQueryWrapper<Wrf> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Wrf::getTemType,0);
lambdaQueryWrapper.eq(Wrf::getSceneType,sceneType);
Wrf wrfInfo = this.baseMapper.selectOne(lambdaQueryWrapper);
private final EventServerProperties eventServerProperties;
private final SystemStorageProperties systemStorageProperties;
private final WeatherDataMapper weatherDataMapper;
if(wrfInfo == null) {
throw new JeecgBootException("未找到对应数据");
@Override
public Result<String> updateWrfInfo(RunProcessParamVO paramVO) {
Date eventDate = DateUtil.parse(paramVO.getEventTime(),"yyyy-MM-dd");
Wrf bizWrf = this.baseMapper.selectOne(new LambdaQueryWrapper<Wrf>().eq(Wrf::getEnginId, paramVO.getEnginId()));
BeanUtil.copyProperties(paramVO, bizWrf);
String format = "yyyy-MM-dd 00:00:00";
Calendar calendar = Calendar.getInstance();
calendar.setTime(eventDate);
calendar.add(Calendar.HOUR_OF_DAY, Integer.valueOf(bizWrf.getAnalogTime()));
bizWrf.setStartTime(DateUtil.format(eventDate,format));
bizWrf.setEndTime(DateUtil.format(calendar.getTime(),format));
bizWrf.setRunDays(Integer.valueOf(bizWrf.getAnalogTime()) / 24 + "");
bizWrf.setTruelat1(paramVO.getRefLat() - 5);
bizWrf.setTruelat2(paramVO.getRefLat() + 5);
bizWrf.setStandLon(paramVO.getRefLon());
this.baseMapper.updateById(bizWrf);
return Result.OK("修改成功!");
}
@Override
public String genWpsShell(String scriptsPath, String fileName, Wrf wrf) throws IOException {
WeatherPathVO weatherPaths = getWeatherPaths(wrf.getWeatherDataType(), wrf.getStartTime(), wrf.getEndTime());
String data = new String(readAllBytes(get(scriptsPath + fileName)));
data = data
.replace("#{fnl_data_root}", weatherPaths.getWeatherPath())
.replace("#{ref_lat}", wrf.getRefLat() + "")
.replace("#{ref_lon}", wrf.getRefLon() + "")
.replace("#{truelat1}", wrf.getTruelat1() + "")
.replace("#{truelat2}", wrf.getTruelat2() + "")
.replace("#{stand_lon}", wrf.getStandLon() + "")
.replace("#{link_grib}", weatherPaths.getLinkGrib());
FileUtil.writeString(data, scriptsPath + fileName, "UTF-8");
return fileName;
}
public WeatherPathVO getWeatherPaths(Integer weatherDataType,String startTime, String endTime) {
WeatherPathVO weatherPathVO = new WeatherPathVO();
String weatherPath = systemStorageProperties.getRootPath() + File.separator;
if (WeatherDataSourceEnum.PANGU.getKey().equals(weatherDataType)) {
weatherPathVO.setWeatherPath(weatherPath + systemStorageProperties.getPangu());
} else if (WeatherDataSourceEnum.GRAPHCAST.getKey().equals(weatherDataType)) {
weatherPathVO.setWeatherPath(weatherPath + systemStorageProperties.getGraphcast());
} else if (WeatherDataSourceEnum.CRA40.getKey().equals(weatherDataType)) {
weatherPathVO.setWeatherPath(weatherPath + systemStorageProperties.getCra40());
} else if (WeatherDataSourceEnum.NCEP.getKey().equals(weatherDataType)) {
weatherPathVO.setWeatherPath(weatherPath + systemStorageProperties.getNcep());
}else if (WeatherDataSourceEnum.FNL.getKey().equals(weatherDataType)) {
weatherPathVO.setWeatherPath(weatherPath + systemStorageProperties.getFnl());
} else if (WeatherDataSourceEnum.T1H.getKey().equals(weatherDataType)) {
weatherPathVO.setWeatherPath(weatherPath + systemStorageProperties.getT1h());
}
// 将String类型的时间转换为LocalDateTime
LocalDateTime start = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime previousDay = start.minusDays(1);
LocalDateTime end = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LambdaQueryWrapper<WeatherData> wrapper = new LambdaQueryWrapper<>();
wrapper.between(WeatherData::getDataStartTime, previousDay, end)
.select(WeatherData::getFilePath, WeatherData::getFilePath);
List<WeatherData> weatherDataList = weatherDataMapper.selectList(wrapper);
String linkGrib = "./link_grib.csh " + weatherDataList.stream().map(data -> data.getFilePath() + " " + data.getFilePath()).collect(Collectors.joining(" "));
weatherPathVO.setLinkGrib(linkGrib);
return weatherPathVO;
}
@Override
public Result<String> runAllWrf(String engId, String scriptsPath, String resultFilePath, String localFilePath) throws IOException {
String cdShRunPath = "cd " + scriptsPath + ";";
boolean wpsSuccess = runProjectWps(cdShRunPath + "chmod +x run_project_wps.sh;./run_project_wps.sh", resultFilePath);
if (!wpsSuccess){
return Result.error("WPS模块运行异常请查看日志信息");
}
return wrfInfo;
RemoteExecuteCommand.runRemoteLinuxCmd(eventServerProperties.getIp(), eventServerProperties.getUsername(), eventServerProperties.getPassword(),
runPyPath(scriptsPath, "update_num_metgrid_levels.py", null));
boolean wrfSuccess = runProjectWrf(cdShRunPath + "chmod +x run_project_wrf.sh;./run_project_wrf.sh", resultFilePath);
if (!wrfSuccess){
return Result.error("WRF模块运行异常请查看日志信息");
}
return Result.ok();
}
public boolean runProjectWps(String cmdString,String resultFilePath) throws IOException {
RemoteExecuteCommand.runRemoteLinuxCmd(eventServerProperties.getIp(), eventServerProperties.getUsername(), eventServerProperties.getPassword(), cmdString);
String metgridLog = new String(readAllBytes(get(resultFilePath + EventConstants.WRF_DIR+ "/metgrid.log")));
if(metgridLog.indexOf("Successful completion of program metgrid.exe") > 0){
return true;
}
return false;
}
public boolean runProjectWrf(String cmdString,String resultFilePath) throws IOException {
RemoteExecuteCommand.runRemoteLinuxCmd(eventServerProperties.getIp(), eventServerProperties.getUsername(), eventServerProperties.getPassword(), cmdString);
String wrfLog = new String(readAllBytes(get(resultFilePath + EventConstants.WRF_DIR + "/rsl.out.0000")));
if(wrfLog.indexOf("SUCCESS COMPLETE WRF") > 0){
return true;
}
return false;
}
public String runPyPath(String scriptsPath,String pyFileName,String param){
return String.format("cd %s;chmod +x %s;%srtm/bin/python3 %s %s", scriptsPath, pyFileName,eventServerProperties.getPythonPath(), pyFileName, param);
}
}

View File

@ -50,9 +50,9 @@ public class DownloadT1hJob {
try {
String baseTime = getBaseTime();
// 第一阶段下载文件
// downloadAllT1hFiles(baseTime);
downloadAllT1hFiles(baseTime);
// 第二阶段合并文件
// mergeT1hFiles(baseTime);
mergeT1hFiles(baseTime);
// 合并后删除原始文件
Arrays.stream(new File(getFullPath(t1hDownloadProperties.getT1hPath())).listFiles()).filter(File::isFile).forEach(File::delete);
// 更新气象文件信息
@ -180,7 +180,7 @@ public class DownloadT1hJob {
processWatch.stop();
if (exitCode == 0) {
log.info("{}脚本执行,耗时: {} 毫秒",
log.info("{}脚本执行成,耗时: {} 毫秒",
processDescription, processWatch.getTotalTimeMillis());
} else {
throw new RuntimeException(processDescription +

View File

@ -61,6 +61,7 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
private final SystemStorageProperties systemStorageProperties;
private final DataSourceTransactionManager transactionManager;
private final TransactionDefinition transactionDefinition;
private final WeatherDataMapper weatherDataMapper;
/**
* 根据类型和小时数获取天气数据
@ -138,11 +139,16 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
@Override
public Map<String, List<String>> getDataLine(Integer dataType, LocalDateTime startTime, LocalDateTime endTime,
double longitude, double latitude) {
// 参数校验
if (startTime == null || endTime == null || startTime.isAfter(endTime)) {
throw new IllegalArgumentException("时间参数无效");
}
List<WeatherData> weatherDataList = weatherDataMapper.selectList(new LambdaQueryWrapper<WeatherData>().
between(WeatherData::getDataStartTime, startTime, endTime).eq(WeatherData::getDataSource,dataType));
if (weatherDataList == null || weatherDataList.isEmpty()) {
throw new IllegalArgumentException("时间范围内没有气象数据");
}
// 初始化结果集
Map<String, List<String>> result = new LinkedHashMap<>(); // 保持插入顺序
List<String> timeList = new ArrayList<>();
@ -158,11 +164,11 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
// 循环处理每个时间点的数据
LocalDateTime currentTime = startTime;
while (!currentTime.isAfter(endTime)) {
String filePath = buildFilePath(currentTime, WeatherTypeEnum.TEMPERATURE.getKey(),
String filePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.TEMPERATURE.getKey(),
WeatherDataSourceEnum.getInfoByKey(dataType));
if (isFileValid(filePath)) {
try {
processCommonData(filePath, gridIndex, currentTime, timeList, temperatureList,
processCommonData(weatherDataList, filePath, gridIndex, currentTime, timeList, temperatureList,
pressureList, humidityList, windSpeedList, dataType);
} catch (Exception e) {
log.error("处理时间点 {} 数据时出错: {}", currentTime, e.getMessage(), e);
@ -525,7 +531,7 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
/**
* 通用数据处理方法
*/
private void processCommonData(String filePath, int[] gridIndex, LocalDateTime currentTime,
private void processCommonData(List<WeatherData> weatherDataList, String filePath, int[] gridIndex, LocalDateTime currentTime,
List<String> timeList, List<String> temperatureList,
List<String> pressureList, List<String> humidityList,
List<String> windSpeedList, Integer dataType) throws IOException {
@ -548,11 +554,11 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
}else {
// 循环处理每个时间点的数据
try {
String tFilePath = buildFilePath(currentTime, WeatherTypeEnum.TEMPERATURE.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String pFilePath = buildFilePath(currentTime, WeatherTypeEnum.PRESSURE.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String hFilePath = buildFilePath(currentTime, WeatherTypeEnum.HUMIDITY.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String uFilePath = buildFilePath(currentTime, WeatherTypeEnum.WIND.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String vFilePath = buildFilePath(currentTime, WeatherTypeEnum.WIND.getKey() + 1, WeatherDataSourceEnum.getInfoByKey(dataType));
String tFilePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.TEMPERATURE.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String pFilePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.PRESSURE.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String hFilePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.HUMIDITY.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String uFilePath = getWeatherFilePath(weatherDataList, currentTime, WeatherTypeEnum.WIND.getKey(), WeatherDataSourceEnum.getInfoByKey(dataType));
String vFilePath = getWeatherFilePath(weatherDataList, currentTime,WeatherTypeEnum.WIND.getKey() + 1, WeatherDataSourceEnum.getInfoByKey(dataType));
List<List<Double>> tData = null;
List<List<Double>> pData = null;
@ -718,8 +724,10 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
* 处理天气数据
*/
private WeatherResultVO processWeatherData(Integer weatherType, LocalDateTime targetTime, WeatherDataSourceEnum dataTypeEnum) {
List<WeatherData> weatherDataList = weatherDataMapper.selectList(new LambdaQueryWrapper<WeatherData>().
eq(WeatherData::getDataStartTime, targetTime).eq(WeatherData::getDataSource,dataTypeEnum.getKey()));
WeatherResultVO weatherResultVO = new WeatherResultVO();
String filePath = buildFilePath(targetTime, weatherType, dataTypeEnum);
String filePath = getWeatherFilePath(weatherDataList, targetTime, weatherType, dataTypeEnum);
validateFile(filePath);
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
@ -730,7 +738,7 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
ValueConverter converter = null;
if (WeatherTypeEnum.WIND.getKey().equals(weatherType)) {
converter = value -> value;
List<List<List<Double>>> windDataList = processWindData(weatherType, targetTime, dataTypeEnum, weatherResultVO);
List<List<List<Double>>> windDataList = processWindData(weatherDataList, weatherType, targetTime, dataTypeEnum);
processResultDataInternal(weatherResultVO, null, windDataList.get(0), windDataList.get(1), lonData, latData, converter);
}else{
List<List<Double>> dataList;
@ -759,11 +767,11 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
/**
* 处理风场数据
*/
private List<List<List<Double>>> processWindData(Integer weatherType, LocalDateTime targetTime,
WeatherDataSourceEnum dataTypeEnum, WeatherResultVO weatherResultVO) {
private List<List<List<Double>>> processWindData(List<WeatherData> weatherDataList, Integer weatherType, LocalDateTime targetTime,
WeatherDataSourceEnum dataTypeEnum) {
List<List<List<Double>>> windDataList = new ArrayList<>();
if (!WeatherDataSourceEnum.CRA40.equals(dataTypeEnum)) {
String filePath = buildFilePath(targetTime, weatherType, dataTypeEnum);
String filePath = getWeatherFilePath(weatherDataList, targetTime, weatherType, dataTypeEnum);
validateFile(filePath);
try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
@ -778,8 +786,8 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
throw new JeecgBootException("文件读取失败", e);
}
} else {
String uFilePath = buildFilePath(targetTime, weatherType, dataTypeEnum);
String vFilePath = buildFilePath(targetTime, weatherType + 1, dataTypeEnum);
String uFilePath = getWeatherFilePath(weatherDataList, targetTime, weatherType, dataTypeEnum);
String vFilePath = getWeatherFilePath(weatherDataList, targetTime,weatherType + 1, dataTypeEnum);
validateFile(uFilePath);
validateFile(vFilePath);
@ -830,7 +838,32 @@ public class WeatherDataServiceImpl extends ServiceImpl<WeatherDataMapper, Weath
}
/**
* 构建文件路径
* 查询文件目录
* @param weatherDataList
* @param currentTime
* @param weatherType
* @param dataTypeEnum
* @return
*/
public String getWeatherFilePath(List<WeatherData> weatherDataList, LocalDateTime currentTime, Integer weatherType, WeatherDataSourceEnum dataTypeEnum){
if (WeatherDataSourceEnum.CRA40.equals(dataTypeEnum)) {
for (WeatherData weatherData : weatherDataList) {
if(weatherData.getFileName().contains(Cra40FilePrefixEnum.getValueByKey(weatherType)) && weatherData.getDataStartTime().equals(currentTime)){
return weatherData.getFilePath();
}
}
} else {
for (WeatherData weatherData : weatherDataList) {
if(weatherData.getDataStartTime().equals(currentTime)){
return weatherData.getFilePath();
}
}
}
throw new RuntimeException("未找到气象数据:" + currentTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
/**
* 构建文件路径(废案)
*/
private String buildFilePath(LocalDateTime targetTime, Integer weatherType, WeatherDataSourceEnum dataTypeEnum) {
StringBuilder storagePath = new StringBuilder()