1.完成源项处理模块新增源项重建任务、获取源项重建监测数据、导出模版、导入源项重建监测数据、执行重建任务、获取单条源项重建任务记录、修改源项重建任务、删除源项重建任务、查询源项重建任务列表、获取源项重建任务过程日志、获取概率分布图数据、获取观测值和模拟值的活度浓度比较结果数据、获取单变量后验分布接口
This commit is contained in:
		
							parent
							
								
									9020bc96fc
								
							
						
					
					
						commit
						00d013ec55
					
				|  | @ -0,0 +1,26 @@ | |||
| package org.jeecg.common.constant.enums; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建释放源是否已知枚举状态说明枚举 | ||||
|  */ | ||||
| public enum SourceRebuildReleaseSourceEnum { | ||||
| 
 | ||||
|     /** | ||||
|      * 未知 | ||||
|      */ | ||||
|     UNKNOWN(0), | ||||
|     /** | ||||
|      * 已知 | ||||
|      */ | ||||
|     KNOWN(1); | ||||
| 
 | ||||
|     private Integer value; | ||||
| 
 | ||||
|     SourceRebuildReleaseSourceEnum(Integer value) { | ||||
|         this.value = value; | ||||
|     } | ||||
| 
 | ||||
|     public Integer getValue(){ | ||||
|         return this.value; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,34 @@ | |||
| package org.jeecg.common.constant.enums; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务状态说明枚举 | ||||
|  */ | ||||
| public enum SourceRebuildTaskStatusEnum { | ||||
| 
 | ||||
|     /** | ||||
|      * 未开始 | ||||
|      */ | ||||
|     ERROR(-1), | ||||
|     /** | ||||
|      * 未开始 | ||||
|      */ | ||||
|     NOT_STARTED(0), | ||||
|     /** | ||||
|      * 执行中 | ||||
|      */ | ||||
|     IN_OPERATION(1), | ||||
|     /** | ||||
|      * 已完成 | ||||
|      */ | ||||
|     COMPLETED(2); | ||||
| 
 | ||||
|     private Integer value; | ||||
| 
 | ||||
|     SourceRebuildTaskStatusEnum(Integer value) { | ||||
|         this.value = value; | ||||
|     } | ||||
| 
 | ||||
|     public Integer getValue(){ | ||||
|         return this.value; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,37 @@ | |||
| package org.jeecg.common.properties; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| @Data | ||||
| @Component | ||||
| @ConfigurationProperties(prefix = "source-rebuild") | ||||
| public class SourceRebuildParams { | ||||
| 
 | ||||
|     /** | ||||
|      * Rserve 服务地址 | ||||
|      */ | ||||
|     private String serverAddr; | ||||
| 
 | ||||
|     /** | ||||
|      * Rserve端口 | ||||
|      */ | ||||
|     private Integer port; | ||||
| 
 | ||||
|     /** | ||||
|      * Rserve 用户名称 | ||||
|      */ | ||||
|     private String username; | ||||
| 
 | ||||
|     /** | ||||
|      * Rserve密码 | ||||
|      */ | ||||
|     private String password; | ||||
| 
 | ||||
|     /** | ||||
|      * R项目工作空间 | ||||
|      */ | ||||
|     private String workSpace; | ||||
| 
 | ||||
| } | ||||
|  | @ -28,4 +28,29 @@ public class SystemStorageProperties { | |||
|      * 再分析数据存储路径 | ||||
|      */ | ||||
|     private String reAnalysis; | ||||
| 
 | ||||
|     /** | ||||
|      * R项目所在路径 | ||||
|      */ | ||||
|     private String rProject; | ||||
| 
 | ||||
|     /** | ||||
|      * R项目输入目录 | ||||
|      */ | ||||
|     private String rInput; | ||||
| 
 | ||||
|     /** | ||||
|      * R项目输出目录 | ||||
|      */ | ||||
|     private String rOutput; | ||||
| 
 | ||||
|     /** | ||||
|      * srs 文件路径 | ||||
|      */ | ||||
|     private String srsFilePath; | ||||
| 
 | ||||
|     /** | ||||
|      * xe文件srs文件所在的目录 | ||||
|      */ | ||||
|     private String xeGZFileDirSign; | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,94 @@ | |||
| package org.jeecg.modules.base.entity; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.annotation.IdType; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.fasterxml.jackson.annotation.JsonFormat; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.Data; | ||||
| import org.jeecg.common.validgroup.InsertGroup; | ||||
| import org.jeecg.common.validgroup.UpdateGroup; | ||||
| import org.jeecgframework.poi.excel.annotation.Excel; | ||||
| import org.springframework.format.annotation.DateTimeFormat; | ||||
| import java.io.Serializable; | ||||
| import java.util.Date; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建监测数据表 | ||||
|  */ | ||||
| @Data | ||||
| @TableName("stas_source_rebuild_monitoring_data") | ||||
| public class SourceRebuildMonitoringData implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * ID | ||||
|      */ | ||||
|     @TableId(type = IdType.AUTO) | ||||
|     private Integer id; | ||||
| 
 | ||||
|     /** | ||||
|      * 任务ID | ||||
|      */ | ||||
|     @Excel(name = "任务主键", width = 10,height = 20,orderNum="0") | ||||
|     @TableField(value = "task_id") | ||||
|     private Integer taskId; | ||||
| 
 | ||||
|     /** | ||||
|      * 台站名称 | ||||
|      */ | ||||
|     @Excel(name = "台站名称", width = 20,height = 20,orderNum="1") | ||||
|     @NotBlank(message = "台站名称不能为空", groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "station") | ||||
|     private String station; | ||||
| 
 | ||||
|     /** | ||||
|      * 核素名称 | ||||
|      */ | ||||
|     @Excel(name = "核素名称", width = 20,height = 20,orderNum="2") | ||||
|     @NotBlank(message = "核素名称不能为空", groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "nuclide") | ||||
|     private String nuclide; | ||||
| 
 | ||||
|     /** | ||||
|      * 测量停止时间 | ||||
|      */ | ||||
|     @Excel(name = "测量停止时间", width = 25,height = 20,format = "yyyy-MM-dd HH:mm:ss",orderNum="3") | ||||
|     @NotNull(message = "测量停止时间不能为空", groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "collect_stop") | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     private Date collectStop; | ||||
| 
 | ||||
|     /** | ||||
|      * 活度浓度 | ||||
|      */ | ||||
|     @Excel(name = "活度浓度", width = 25,height = 20,orderNum="4") | ||||
|     @NotBlank(message = "活度浓度不能为空", groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "activity") | ||||
|     private String activity; | ||||
| 
 | ||||
|     /** | ||||
|      * 不确定度 | ||||
|      */ | ||||
|     @Excel(name = "不确定度", width = 25,height = 20,orderNum="5") | ||||
|     @NotBlank(message = "不确定度不能为空", groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "uncertainty") | ||||
|     private String uncertainty; | ||||
| 
 | ||||
|     /** | ||||
|      * mdc | ||||
|      */ | ||||
|     @Excel(name = "MDC", width = 25,height = 20,orderNum="6") | ||||
|     @NotBlank(message = "mdc不能为空", groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "mdc") | ||||
|     private String mdc; | ||||
| 
 | ||||
|      /** | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     @TableField(value = "create_time") | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     private Date createTime; | ||||
| } | ||||
|  | @ -0,0 +1,206 @@ | |||
| package org.jeecg.modules.base.entity; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.annotation.IdType; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.fasterxml.jackson.annotation.JsonFormat; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import jakarta.validation.constraints.Null; | ||||
| import lombok.Data; | ||||
| import org.jeecg.common.validgroup.InsertGroup; | ||||
| import org.jeecg.common.validgroup.UpdateGroup; | ||||
| import org.springframework.format.annotation.DateTimeFormat; | ||||
| import java.io.Serializable; | ||||
| import java.util.Date; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务表 | ||||
|  */ | ||||
| @Data | ||||
| @TableName("stas_source_rebuild") | ||||
| public class SourceRebuildTask implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * ID | ||||
|      */ | ||||
|     @Null(message = "ID必须为空",groups = { InsertGroup.class}) | ||||
|     @NotNull(message = "ID不能为空",groups = { UpdateGroup.class}) | ||||
|     @TableId(type = IdType.AUTO) | ||||
|     private Integer id; | ||||
| 
 | ||||
|     /** | ||||
|      * 任务名称 | ||||
|      */ | ||||
|     @NotBlank(message = "任务名称不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "task_name") | ||||
|     private String taskName; | ||||
| 
 | ||||
|     /** | ||||
|      * 任务状态-1执行错误,0-未开始,1进行中,2已完成 | ||||
|      */ | ||||
|     @Null(message = "任务状态必须为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "task_status") | ||||
|     private Integer taskStatus; | ||||
| 
 | ||||
|     /** | ||||
|      * 最小经度 | ||||
|      */ | ||||
|     @NotNull(message = "最小经度不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "lonmin") | ||||
|     private Double lonmin; | ||||
| 
 | ||||
|     /** | ||||
|      * 最小纬度 | ||||
|      */ | ||||
|     @NotNull(message = "最小纬度不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "latmin") | ||||
|     private Double latmin; | ||||
| 
 | ||||
|     /** | ||||
|      * 最大经度 | ||||
|      */ | ||||
|     @NotNull(message = "最大经度不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "lonmax") | ||||
|     private Double lonmax; | ||||
| 
 | ||||
|     /** | ||||
|      * 最大纬度 | ||||
|      */ | ||||
|     @NotNull(message = "最大纬度不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "latmax") | ||||
|     private Double latmax; | ||||
| 
 | ||||
|     /** | ||||
|      * 分辨率 | ||||
|      */ | ||||
|     @NotNull(message = "分辨率不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "resolution") | ||||
|     private String resolution; | ||||
| 
 | ||||
|     /** | ||||
|      * srs时间周期-开始日期 | ||||
|      */ | ||||
|     @NotNull(message = "srs时间周期-开始日期不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") | ||||
|     @TableField(value = "srs_start_time") | ||||
|     private Date srsStartTime; | ||||
| 
 | ||||
|     /** | ||||
|      * srs时间周期-结束日期 | ||||
|      */ | ||||
|     @NotNull(message = "srs时间周期-结束日期不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") | ||||
|     @TableField(value = "srs_end_time") | ||||
|     private Date srsEndTime; | ||||
| 
 | ||||
|     /** | ||||
|      * 释放类型,1-持续释放,2-均匀释放,3-非均匀释放 | ||||
|      */ | ||||
|     @NotNull(message = "释放源类型不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "release_type") | ||||
|     private Integer releaseType; | ||||
| 
 | ||||
|     /** | ||||
|      * 释放源位置,0-未知,1已知 | ||||
|      */ | ||||
|     @NotNull(message = "是否已知释放源不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "release_source_location") | ||||
|     private Integer releaseSourceLocation; | ||||
| 
 | ||||
|     /** | ||||
|      * 释放源经度 | ||||
|      */ | ||||
|     @TableField(value = "source_lon") | ||||
|     private Double sourceLon; | ||||
| 
 | ||||
|     /** | ||||
|      * 释放源纬度 | ||||
|      */ | ||||
|     @TableField(value = "source_lat") | ||||
|     private Double sourceLat; | ||||
| 
 | ||||
|     /** | ||||
|      * 释放源开始释放时间 | ||||
|      */ | ||||
|     @TableField(value = "release_start_time") | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") | ||||
|     private Date releaseStartTime; | ||||
| 
 | ||||
|     /** | ||||
|      * 释放源结束释放时间 | ||||
|      */ | ||||
|     @TableField(value = "release_end_time") | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") | ||||
|     private Date releaseEndTime; | ||||
| 
 | ||||
|     /** | ||||
|      * 源强 | ||||
|      */ | ||||
|     @TableField(value = "source_strength") | ||||
|     private Integer sourceStrength; | ||||
| 
 | ||||
|     /** | ||||
|      * 耗时 | ||||
|      */ | ||||
|     @Null(message = "耗时必须为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "time_consuming") | ||||
|     private Integer timeConsuming; | ||||
| 
 | ||||
|     /** | ||||
|      * 半衰期 | ||||
|      */ | ||||
|     @NotNull(message = "半衰期不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "halflife") | ||||
|     private Double halflife; | ||||
| 
 | ||||
|     /** | ||||
|      * 最小总累积源项Bq | ||||
|      */ | ||||
|     @NotNull(message = "最小总累积源项Bq不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "qmin") | ||||
|     private Integer qmin; | ||||
| 
 | ||||
|     /** | ||||
|      * 最大总累积源项Bq | ||||
|      */ | ||||
|     @NotNull(message = "最大总累积源项Bq不能为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "qmax") | ||||
|     private Integer qmax; | ||||
| 
 | ||||
|     /** | ||||
|      * 结果存储地址 | ||||
|      */ | ||||
|     @Null(message = "结果存储地址必须为空",groups = {InsertGroup.class, UpdateGroup.class}) | ||||
|     @TableField(value = "result_address") | ||||
|     private String resultAddress; | ||||
| 
 | ||||
|     /** | ||||
|      * 创建人 | ||||
|      */ | ||||
|     @TableField(value = "create_by") | ||||
|     private String createBy; | ||||
| 
 | ||||
|     /** | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     @TableField(value = "create_time") | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     private Date createTime; | ||||
| 
 | ||||
|     /** | ||||
|      * 更新人 | ||||
|      */ | ||||
|     @TableField(value = "update_by") | ||||
|     private String updateBy; | ||||
| 
 | ||||
|     /** | ||||
|      * 更新时间 | ||||
|      */ | ||||
|     @TableField(value = "update_time") | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     private Date updateTime; | ||||
| } | ||||
|  | @ -0,0 +1,51 @@ | |||
| package org.jeecg.modules.base.entity; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.annotation.IdType; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.fasterxml.jackson.annotation.JsonFormat; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import org.springframework.format.annotation.DateTimeFormat; | ||||
| import java.io.Serializable; | ||||
| import java.util.Date; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务日志表 | ||||
|  */ | ||||
| @Data | ||||
| @NoArgsConstructor | ||||
| @TableName("stas_source_rebuild_task_log") | ||||
| public class SourceRebuildTaskLog implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * ID | ||||
|      */ | ||||
|     @TableId(type = IdType.AUTO) | ||||
|     private Integer id; | ||||
| 
 | ||||
|     /** | ||||
|      * 任务id | ||||
|      */ | ||||
|     @TableField(value = "task_id") | ||||
|     private Integer taskId; | ||||
| 
 | ||||
|     /** | ||||
|      * 创建时间 | ||||
|      */ | ||||
|     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||||
|     private Date createTime; | ||||
| 
 | ||||
|     /** | ||||
|      * 日志内容 | ||||
|      */ | ||||
|     @TableField(value = "log_content") | ||||
|     private String logContent; | ||||
| 
 | ||||
|     public SourceRebuildTaskLog(Integer taskId, String logContent) { | ||||
|         this.taskId = taskId; | ||||
|         this.logContent = logContent; | ||||
|     } | ||||
| } | ||||
|  | @ -7,6 +7,8 @@ import com.baomidou.mybatisplus.annotation.TableName; | |||
| import com.fasterxml.jackson.annotation.JsonFormat; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.Date; | ||||
| 
 | ||||
|  | @ -15,7 +17,7 @@ import java.util.Date; | |||
|  */ | ||||
| @Data | ||||
| @TableName("stas_weather_data") | ||||
| public class WeatherData { | ||||
| public class WeatherData implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * ID | ||||
|  |  | |||
|  | @ -7,6 +7,8 @@ import com.baomidou.mybatisplus.annotation.TableName; | |||
| import com.fasterxml.jackson.annotation.JsonFormat; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDateTime; | ||||
| 
 | ||||
| /** | ||||
|  | @ -14,7 +16,7 @@ import java.time.LocalDateTime; | |||
|  */ | ||||
| @Data | ||||
| @TableName("stas_weather_task_log") | ||||
| public class WeatherTaskLog{ | ||||
| public class WeatherTaskLog implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * ID | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| package org.jeecg.modules.base.mapper; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildMonitoringData; | ||||
| 
 | ||||
| public interface SourceRebuildMonitoringDataMapper extends BaseMapper<SourceRebuildMonitoringData> { | ||||
| } | ||||
|  | @ -0,0 +1,8 @@ | |||
| package org.jeecg.modules.base.mapper; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTaskLog; | ||||
| 
 | ||||
| public interface SourceRebuildTaskLogMapper extends BaseMapper<SourceRebuildTaskLog> { | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,7 @@ | |||
| package org.jeecg.modules.base.mapper; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTask; | ||||
| 
 | ||||
| public interface SourceRebuildTaskMapper extends BaseMapper<SourceRebuildTask> { | ||||
| } | ||||
|  | @ -0,0 +1,5 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||||
| <mapper namespace="org.jeecg.modules.base.mapper.SourceRebuildMonitoringDataMapper"> | ||||
| 
 | ||||
| </mapper> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||||
| <mapper namespace="org.jeecg.modules.base.mapper.SourceRebuildTaskLogMapper"> | ||||
| 
 | ||||
| </mapper> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||||
| <mapper namespace="org.jeecg.modules.base.mapper.SourceRebuildTaskMapper"> | ||||
| 
 | ||||
| </mapper> | ||||
|  | @ -9,12 +9,14 @@ | |||
|         <version>3.8.1</version> | ||||
|     </parent> | ||||
| 
 | ||||
|     <artifactId>jeecg-module-sourceitem-reconstruction</artifactId> | ||||
|     <artifactId>jeecg-module-source-rebuild</artifactId> | ||||
| 
 | ||||
|     <properties> | ||||
|         <maven.compiler.source>17</maven.compiler.source> | ||||
|         <maven.compiler.target>17</maven.compiler.target> | ||||
|         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
|         <rEngine.version>2.1.0</rEngine.version> | ||||
|         <rserve.version>1.8.1</rserve.version> | ||||
|     </properties> | ||||
| 
 | ||||
|     <dependencies> | ||||
|  | @ -23,5 +25,15 @@ | |||
|             <artifactId>jeecg-boot-base-core</artifactId> | ||||
|             <version>${jeecgboot.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.rosuda.REngine</groupId> | ||||
|             <artifactId>REngine</artifactId> | ||||
|             <version>${rEngine.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.rosuda.REngine</groupId> | ||||
|             <artifactId>Rserve</artifactId> | ||||
|             <version>${rserve.version}</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| </project> | ||||
|  | @ -0,0 +1,90 @@ | |||
| package org.jeecg.controller; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import io.swagger.v3.oas.annotations.Operation; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.jeecg.common.api.vo.Result; | ||||
| import org.jeecg.common.aspect.annotation.AutoLog; | ||||
| import org.jeecg.common.system.query.PageRequest; | ||||
| import org.jeecg.common.validgroup.InsertGroup; | ||||
| import org.jeecg.common.validgroup.UpdateGroup; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTask; | ||||
| import org.jeecg.service.SourceRebuildTaskService; | ||||
| import org.springframework.format.annotation.DateTimeFormat; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import java.time.LocalDate; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建 | ||||
|  */ | ||||
| @Validated | ||||
| @RestController | ||||
| @RequiredArgsConstructor | ||||
| @RequestMapping("source") | ||||
| public class SourceRebuildTaskController{ | ||||
| 
 | ||||
|     private final SourceRebuildTaskService sourceRebuildTaskService; | ||||
| 
 | ||||
|     @AutoLog(value = "查询源项重建任务列表") | ||||
|     @Operation(summary = "查询源项重建任务列表") | ||||
|     @GetMapping(value = "page") | ||||
|     public Result<?> page(PageRequest pageRequest, String taskName, Integer taskStatus, | ||||
|                           @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, | ||||
|                           @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) { | ||||
|         IPage<SourceRebuildTask> page = sourceRebuildTaskService.page(pageRequest, taskName, taskStatus, startDate,endDate); | ||||
|         Map<String, Object> rspData = new HashMap<>(); | ||||
|         rspData.put("rows", page.getRecords()); | ||||
|         rspData.put("total", page.getTotal()); | ||||
|         return Result.OK(rspData); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "新增源项重建任务") | ||||
|     @Operation(summary = "新增源项重建任务") | ||||
|     @PostMapping("create") | ||||
|     public Result<?> create(@RequestBody @Validated(value = InsertGroup.class) SourceRebuildTask sourceRebuildTask){ | ||||
|         sourceRebuildTaskService.cteate(sourceRebuildTask); | ||||
|         return Result.OK(); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "获取单条源项重建任务记录") | ||||
|     @Operation(summary = "获取单条源项重建任务记录") | ||||
|     @GetMapping("getById") | ||||
|     public Result<?> getById(@NotNull(message = "ID不能为空") String id){ | ||||
|         return Result.OK(sourceRebuildTaskService.getById(id)); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "修改源项重建任务") | ||||
|     @Operation(summary = "修改源项重建任务") | ||||
|     @PutMapping("update") | ||||
|     public Result<?> update(@RequestBody @Validated(value = UpdateGroup.class) SourceRebuildTask sourceRebuildTask){ | ||||
|         sourceRebuildTaskService.update(sourceRebuildTask); | ||||
|         return Result.OK(); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "删除源项重建任务") | ||||
|     @Operation(summary = "删除源项重建任务") | ||||
|     @DeleteMapping("delete") | ||||
|     public Result<?> delete(@NotNull(message = "id不能为空") Integer id){ | ||||
|         sourceRebuildTaskService.delete(id); | ||||
|         return Result.OK(); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "获取源项重建任务过程日志") | ||||
|     @Operation(summary = "获取源项重建任务过程日志") | ||||
|     @GetMapping("getTaskLog") | ||||
|     public Result<?> getTaskLog(@NotNull(message = "任务ID不能为空") Integer taskId){ | ||||
|         return Result.OK(sourceRebuildTaskService.getTaskLog(taskId)); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "启动任务") | ||||
|     @Operation(summary = "启动任务") | ||||
|     @PutMapping("runTask") | ||||
|     public Result<?> runTask(@NotNull(message = "任务ID不能为空") Integer taskId){ | ||||
|         sourceRebuildTaskService.runTask(taskId); | ||||
|         return Result.OK(); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,95 @@ | |||
| package org.jeecg.controller; | ||||
| 
 | ||||
| import io.swagger.v3.oas.annotations.Operation; | ||||
| import jakarta.servlet.http.HttpServletRequest; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.jeecg.common.api.vo.Result; | ||||
| import org.jeecg.common.aspect.annotation.AutoLog; | ||||
| import org.jeecg.common.system.base.controller.JeecgController; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildMonitoringData; | ||||
| import org.jeecg.service.SourceRebuildMonitoringDataService; | ||||
| import org.jeecgframework.poi.excel.ExcelExportUtil; | ||||
| import org.jeecgframework.poi.excel.ExcelImportCheckUtil; | ||||
| import org.jeecgframework.poi.excel.ExcelImportUtil; | ||||
| import org.jeecgframework.poi.excel.entity.ExportParams; | ||||
| import org.jeecgframework.poi.excel.entity.ImportParams; | ||||
| import org.jeecgframework.poi.excel.entity.enmus.ExcelType; | ||||
| import org.springframework.beans.BeanUtils; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
| import org.springframework.web.multipart.MultipartHttpServletRequest; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务监测数据 | ||||
|  */ | ||||
| @Slf4j | ||||
| @Validated | ||||
| @RestController | ||||
| @RequiredArgsConstructor | ||||
| @RequestMapping("source") | ||||
| public class TaskMonitoringDataController { | ||||
| 
 | ||||
|     private final SourceRebuildMonitoringDataService monitoringDataService; | ||||
| 
 | ||||
|     @AutoLog(value = "获取源项重建监测数据") | ||||
|     @Operation(summary = "获取源项重建监测数据") | ||||
|     @GetMapping("getTaskMonitoringData") | ||||
|     public Result<?> getTaskMonitoringData(@NotNull(message = "任务ID不能为空") Integer taskId){ | ||||
|         return Result.OK(monitoringDataService.getTaskMonitoringData(taskId)); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "导出模版") | ||||
|     @Operation(summary = "导出模版") | ||||
|     @GetMapping("exportTemplate") | ||||
|     public void exportTemplate(HttpServletResponse response) throws IOException { | ||||
|         ExportParams params = new ExportParams(); | ||||
|         params.setTitle("台站监测数据"); | ||||
|         params.setFixedTitle(true); | ||||
|         params.setTitleHeight((short) 8); | ||||
|         params.setType(ExcelType.XSSF); | ||||
|         ExcelExportUtil.exportExcel(params,SourceRebuildMonitoringData.class,new ArrayList<>()).write(response.getOutputStream()); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "导入源项重建监测数据") | ||||
|     @Operation(summary = "导入源项重建监测数据") | ||||
|     @PostMapping("importTaskMonitoringData") | ||||
|     public Result<?> importTaskMonitoringData(HttpServletRequest request, HttpServletResponse response){ | ||||
|         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; | ||||
|         Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); | ||||
|         for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) { | ||||
|             // 获取上传文件对象 | ||||
|             MultipartFile file = entity.getValue(); | ||||
|             ImportParams params = new ImportParams(); | ||||
|             params.setTitleRows(1); | ||||
|             params.setHeadRows(2); | ||||
|             params.setNeedSave(true); | ||||
|             try { | ||||
|                 ExcelImportCheckUtil.check(file.getInputStream(), SourceRebuildMonitoringData.class, params); | ||||
|                 List<SourceRebuildMonitoringData> list = ExcelImportUtil.importExcel(file.getInputStream(), SourceRebuildMonitoringData.class, params); | ||||
|                 System.out.println(list); | ||||
|                 monitoringDataService.cteate(list); | ||||
|                 return Result.ok("文件导入成功!"); | ||||
|             } catch (Exception e) { | ||||
|                 log.error(e.getMessage(), e); | ||||
|                 return Result.error("文件导入失败:" + e.getMessage()); | ||||
|             } finally { | ||||
|                 try { | ||||
|                     file.getInputStream().close(); | ||||
|                 } catch (Exception e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return Result.error("文件导入失败!"); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,57 @@ | |||
| package org.jeecg.controller; | ||||
| 
 | ||||
| import io.swagger.v3.oas.annotations.Operation; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.NotNull; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.jeecg.common.api.vo.Result; | ||||
| import org.jeecg.common.aspect.annotation.AutoLog; | ||||
| import org.jeecg.service.SourceRebuildMonitoringDataService; | ||||
| import org.jeecg.service.TaskResultDataService; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务运行结果数据 | ||||
|  */ | ||||
| @Slf4j | ||||
| @Validated | ||||
| @RestController | ||||
| @RequiredArgsConstructor | ||||
| @RequestMapping("source") | ||||
| public class TaskResultDataController { | ||||
| 
 | ||||
|     private final TaskResultDataService taskResultDataService; | ||||
| 
 | ||||
|     @AutoLog(value = "获取概率分布数据") | ||||
|     @Operation(summary = "获取概率分布数据") | ||||
|     @GetMapping("getBayesProbLoc") | ||||
|     public Result<?> getBayesProbLoc(@NotNull(message = "任务ID不能为空") Integer taskId){ | ||||
|         return Result.OK(taskResultDataService.getBayesProbLoc(taskId)); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "获取观测值和模拟值的活度浓度比较结果数据") | ||||
|     @Operation(summary = "获取观测值和模拟值的活度浓度比较结果数据") | ||||
|     @GetMapping("getBayesAcTimeSeries") | ||||
|     public Result<?> getBayesAcTimeSeries(@NotNull(message = "任务ID不能为空") Integer taskId){ | ||||
|         return Result.OK(taskResultDataService.getBayesAcTimeSeries(taskId)); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "获取单变量后验分布") | ||||
|     @Operation(summary = "获取单变量后验分布") | ||||
|     @GetMapping("getBayesMonovarPosterior") | ||||
|     public Result<?> getBayesMonovarPosterior(@NotNull(message = "任务ID不能为空") Integer taskId){ | ||||
|         return Result.OK(taskResultDataService.getBayesMonovarPosterior(taskId)); | ||||
|     } | ||||
| 
 | ||||
|     @AutoLog(value = "导出TXT") | ||||
|     @Operation(summary = "导出TXT") | ||||
|     @GetMapping("exportTxt") | ||||
|     public void exportTxt(HttpServletResponse response) throws IOException { | ||||
| 
 | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,31 @@ | |||
| package org.jeecg.service; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.extension.service.IService; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildMonitoringData; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务监测数据 | ||||
|  */ | ||||
| public interface SourceRebuildMonitoringDataService extends IService<SourceRebuildMonitoringData> { | ||||
| 
 | ||||
|     /** | ||||
|      * 保存源项重建任务监测数据 | ||||
|      * @param monitoringDatas | ||||
|      */ | ||||
|     void cteate(List<SourceRebuildMonitoringData> monitoringDatas); | ||||
| 
 | ||||
|     /** | ||||
|      * 删除源项重建任务监测数据 | ||||
|      * @param taskId | ||||
|      */ | ||||
|     void delete(Integer taskId); | ||||
| 
 | ||||
|     /** | ||||
|      * 获取任务所属监测数据 | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     List<SourceRebuildMonitoringData> getTaskMonitoringData(Integer taskId); | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,36 @@ | |||
| package org.jeecg.service; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.extension.service.IService; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTaskLog; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务日志数据 | ||||
|  */ | ||||
| public interface SourceRebuildTaskLogService extends IService<SourceRebuildTaskLog> { | ||||
| 
 | ||||
|     /** | ||||
|      * 保存源项重建任务运行过程日志 | ||||
|      * @param sourceRebuildTaskLog | ||||
|      */ | ||||
|     void cteate(SourceRebuildTaskLog sourceRebuildTaskLog); | ||||
| 
 | ||||
|     /** | ||||
|      * 删除任务运行过程日志 | ||||
|      * @param taskId | ||||
|      */ | ||||
|     void delete(Integer taskId); | ||||
| 
 | ||||
|     /** | ||||
|      * 获取任务运行过程日志 | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     List<SourceRebuildTaskLog> getTaskLogs(Integer taskId); | ||||
| 
 | ||||
|     /** | ||||
|      * 批量保存日志 | ||||
|      * @param logs | ||||
|      */ | ||||
|     void batchCteate(List<SourceRebuildTaskLog> logs); | ||||
| } | ||||
|  | @ -0,0 +1,79 @@ | |||
| package org.jeecg.service; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import com.baomidou.mybatisplus.extension.service.IService; | ||||
| import org.jeecg.common.system.query.PageRequest; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTask; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTaskLog; | ||||
| 
 | ||||
| import java.time.LocalDate; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务 | ||||
|  */ | ||||
| public interface SourceRebuildTaskService extends IService<SourceRebuildTask> { | ||||
| 
 | ||||
|     /** | ||||
|      * 分页查询任务列表 | ||||
|      * @param pageRequest | ||||
|      * @param taskName | ||||
|      * @param taskStatus | ||||
|      * @param startDate | ||||
|      * @param endDate | ||||
|      * @return | ||||
|      */ | ||||
|     IPage<SourceRebuildTask> page(PageRequest pageRequest, String taskName, Integer taskStatus, LocalDate startDate, LocalDate endDate); | ||||
| 
 | ||||
|     /** | ||||
|      * 创建源项重建任务 | ||||
|      * @param sourceItemRebuildTask | ||||
|      */ | ||||
|     void cteate(SourceRebuildTask sourceItemRebuildTask); | ||||
| 
 | ||||
|     /** | ||||
|      * 获取单条任务数据 | ||||
|      * @param id | ||||
|      * @return | ||||
|      */ | ||||
|     SourceRebuildTask getById(Integer id); | ||||
| 
 | ||||
|     /** | ||||
|      * 修改源项重建任务 | ||||
|      * @param sourceRebuildTask | ||||
|      */ | ||||
|     void update(SourceRebuildTask sourceRebuildTask); | ||||
| 
 | ||||
|     /** | ||||
|      * 删除源项重建任务 | ||||
|      * @param id | ||||
|      */ | ||||
|     void delete(Integer id); | ||||
| 
 | ||||
|     /** | ||||
|      * 运行任务 | ||||
|      * @param id | ||||
|      */ | ||||
|     void runTask(Integer id); | ||||
| 
 | ||||
|     /** | ||||
|      * 获取任务运行日志 | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     List<SourceRebuildTaskLog> getTaskLog(Integer taskId); | ||||
| 
 | ||||
|     /** | ||||
|      * 修改任务状态 | ||||
|      * @param taskId | ||||
|      * @param taskStatus | ||||
|      */ | ||||
|     void updateTaskStatus(Integer taskId, Integer taskStatus); | ||||
| 
 | ||||
|     /** | ||||
|      * 任务耗时 | ||||
|      * @param taskId | ||||
|      * @param taskTimeConsuming | ||||
|      */ | ||||
|     void updateTaskTimeConsuming(Integer taskId, Integer taskTimeConsuming); | ||||
| } | ||||
|  | @ -0,0 +1,38 @@ | |||
| package org.jeecg.service; | ||||
| 
 | ||||
| import org.jeecg.vo.ActivityConcComparResult; | ||||
| import org.jeecg.vo.SourceProbabilityGrid; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 任务结果数据 | ||||
|  */ | ||||
| public interface TaskResultDataService { | ||||
| 
 | ||||
|     /** | ||||
|      * 获取概率分布数据 | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     SourceProbabilityGrid getBayesProbLoc(Integer taskId); | ||||
| 
 | ||||
|     /** | ||||
|      * 获取观测值和模拟值的活度浓度比较结果数据 | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     ActivityConcComparResult getBayesAcTimeSeries(Integer taskId); | ||||
| 
 | ||||
|     /** | ||||
|      * 获取双变量后验分布 | ||||
|      * @param taskId | ||||
|      */ | ||||
|     void getBayesBivarPosterior(Integer taskId); | ||||
| 
 | ||||
|     /** | ||||
|      * 获取单变量后验分布 | ||||
|      * @param taskId | ||||
|      */ | ||||
|     Map<String,Object> getBayesMonovarPosterior(Integer taskId); | ||||
| } | ||||
|  | @ -0,0 +1,58 @@ | |||
| package org.jeecg.service.impl; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildMonitoringData; | ||||
| import org.jeecg.modules.base.mapper.SourceRebuildMonitoringDataMapper; | ||||
| import org.jeecg.service.SourceRebuildMonitoringDataService; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务监测数据 | ||||
|  */ | ||||
| @Service | ||||
| @RequiredArgsConstructor | ||||
| public class SourceRebuildMonitoringDataServiceImpl extends ServiceImpl<SourceRebuildMonitoringDataMapper, SourceRebuildMonitoringData> implements SourceRebuildMonitoringDataService { | ||||
| 
 | ||||
|     /** | ||||
|      * 保存源项重建任务监测数据 | ||||
|      * | ||||
|      * @param monitoringDatas | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void cteate(List<SourceRebuildMonitoringData> monitoringDatas) { | ||||
|         this.saveBatch(monitoringDatas); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 删除源项重建任务监测数据 | ||||
|      * | ||||
|      * @param taskId | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void delete(Integer taskId) { | ||||
|         LambdaQueryWrapper<SourceRebuildMonitoringData> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(SourceRebuildMonitoringData::getTaskId, taskId); | ||||
|         this.remove(queryWrapper); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取任务所属监测数据 | ||||
|      * | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     @Override | ||||
|     public List<SourceRebuildMonitoringData> getTaskMonitoringData(Integer taskId) { | ||||
|         LambdaQueryWrapper<SourceRebuildMonitoringData> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(SourceRebuildMonitoringData::getTaskId, taskId); | ||||
|         queryWrapper.ne(SourceRebuildMonitoringData::getStation,"USX77"); | ||||
|         queryWrapper.orderByAsc(SourceRebuildMonitoringData::getCollectStop); | ||||
|         return this.baseMapper.selectList(queryWrapper); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,63 @@ | |||
| package org.jeecg.service.impl; | ||||
| 
 | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTaskLog; | ||||
| import org.jeecg.modules.base.mapper.SourceRebuildTaskLogMapper; | ||||
| import org.jeecg.service.SourceRebuildTaskLogService; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| @Service | ||||
| public class SourceRebuildTaskLogServiceImpl extends ServiceImpl<SourceRebuildTaskLogMapper, SourceRebuildTaskLog> implements SourceRebuildTaskLogService { | ||||
| 
 | ||||
|     /** | ||||
|      * 保存源项重建任务运行过程日志 | ||||
|      * | ||||
|      * @param sourceRebuildTaskLog | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void cteate(SourceRebuildTaskLog sourceRebuildTaskLog) { | ||||
|         this.baseMapper.insert(sourceRebuildTaskLog); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 删除任务运行过程日志 | ||||
|      * | ||||
|      * @param taskId | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void delete(Integer taskId) { | ||||
|         LambdaQueryWrapper<SourceRebuildTaskLog> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(SourceRebuildTaskLog::getTaskId, taskId); | ||||
|         this.baseMapper.delete(queryWrapper); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取任务运行过程日志 | ||||
|      * | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     @Override | ||||
|     public List<SourceRebuildTaskLog> getTaskLogs(Integer taskId) { | ||||
|         LambdaQueryWrapper<SourceRebuildTaskLog> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(SourceRebuildTaskLog::getTaskId, taskId); | ||||
|         return this.baseMapper.selectList(queryWrapper); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 批量保存日志 | ||||
|      * | ||||
|      * @param logs | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void batchCteate(List<SourceRebuildTaskLog> logs) { | ||||
|         this.saveBatch(logs); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,233 @@ | |||
| package org.jeecg.service.impl; | ||||
| 
 | ||||
| import cn.hutool.core.io.FileUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.jeecg.common.constant.enums.SourceRebuildTaskStatusEnum; | ||||
| import org.jeecg.common.properties.SourceRebuildParams; | ||||
| import org.jeecg.common.properties.SystemStorageProperties; | ||||
| import org.jeecg.common.system.query.PageRequest; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildMonitoringData; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTask; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTaskLog; | ||||
| import org.jeecg.modules.base.mapper.SourceRebuildTaskLogMapper; | ||||
| import org.jeecg.modules.base.mapper.SourceRebuildTaskMapper; | ||||
| import org.jeecg.service.SourceRebuildMonitoringDataService; | ||||
| import org.jeecg.service.SourceRebuildTaskLogService; | ||||
| import org.jeecg.service.SourceRebuildTaskService; | ||||
| import org.jeecg.task.SourceRebuildTaskExec; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| import org.springframework.util.CollectionUtils; | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| /** | ||||
|  * 源项重建任务 | ||||
|  */ | ||||
| @Service | ||||
| @RequiredArgsConstructor | ||||
| public class SourceRebuildTaskServiceImpl extends ServiceImpl<SourceRebuildTaskMapper, SourceRebuildTask> implements SourceRebuildTaskService { | ||||
| 
 | ||||
|     private final SourceRebuildTaskLogMapper sourceRebuildTaskLogMapper; | ||||
|     private final SourceRebuildMonitoringDataService monitoringDataService; | ||||
|     private final SourceRebuildTaskLogService sourceRebuildTaskLogService; | ||||
|     private final SystemStorageProperties  systemStorageProperties; | ||||
|     private final SourceRebuildParams sourceRebuildParams; | ||||
| 
 | ||||
|     /** | ||||
|      * 分页查询任务列表 | ||||
|      * @param pageRequest | ||||
|      * @param taskName | ||||
|      * @param taskStatus | ||||
|      * @param startDate | ||||
|      * @param endDate | ||||
|      * @return | ||||
|      */ | ||||
|     @Override | ||||
|     public IPage<SourceRebuildTask> page(PageRequest pageRequest, String taskName, Integer taskStatus, LocalDate startDate, LocalDate endDate) { | ||||
|         LambdaQueryWrapper<SourceRebuildTask> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(Objects.nonNull(taskStatus),SourceRebuildTask::getTaskStatus, taskStatus); | ||||
|         if(Objects.nonNull(startDate) && Objects.nonNull(endDate)){ | ||||
|             LocalDateTime startDateTime = startDate.atTime(0, 0, 0); | ||||
|             LocalDateTime endDateTime = endDate.atTime(23, 59, 59); | ||||
|             queryWrapper.between(SourceRebuildTask::getCreateTime,startDateTime,endDateTime); | ||||
|         } | ||||
|         queryWrapper.like(StringUtils.isNotBlank(taskName),SourceRebuildTask::getTaskName,taskName); | ||||
|         queryWrapper.orderByDesc(SourceRebuildTask::getCreateTime); | ||||
| 
 | ||||
|         IPage<SourceRebuildTask> iPage = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize()); | ||||
|         return this.page(iPage, queryWrapper); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 创建源项重建任务 | ||||
|      * @param sourceRebuildTask | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void cteate(SourceRebuildTask sourceRebuildTask) { | ||||
|         LambdaQueryWrapper<SourceRebuildTask> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(SourceRebuildTask::getTaskName, sourceRebuildTask.getTaskName()); | ||||
|         SourceRebuildTask checkNameResult = this.baseMapper.selectOne(queryWrapper); | ||||
|         if (Objects.nonNull(checkNameResult)) { | ||||
|             throw new RuntimeException("此任务已存在"); | ||||
|         } | ||||
|         sourceRebuildTask.setTaskStatus(SourceRebuildTaskStatusEnum.NOT_STARTED.getValue()); | ||||
|         this.baseMapper.insert(sourceRebuildTask); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取单条任务数据 | ||||
|      * @param id | ||||
|      * @return | ||||
|      */ | ||||
|     @Override | ||||
|     public SourceRebuildTask getById(Integer id) { | ||||
|         SourceRebuildTask sourceRebuildTask = this.baseMapper.selectById(id); | ||||
|         if(Objects.isNull(sourceRebuildTask)){ | ||||
|             throw new RuntimeException("此任务不存在"); | ||||
|         } | ||||
|         return sourceRebuildTask; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 修改源项重建任务 | ||||
|      * @param sourceRebuildTask | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void update(SourceRebuildTask sourceRebuildTask) { | ||||
|         SourceRebuildTask checkIdResult = this.baseMapper.selectById(sourceRebuildTask.getId()); | ||||
|         if (Objects.isNull(checkIdResult)) { | ||||
|             throw new RuntimeException("此任务不存在"); | ||||
|         } | ||||
|         LambdaQueryWrapper<SourceRebuildTask> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(SourceRebuildTask::getTaskName, sourceRebuildTask.getTaskName()); | ||||
|         SourceRebuildTask checkcheckNameResult = this.baseMapper.selectOne(queryWrapper); | ||||
|         if (Objects.nonNull(checkcheckNameResult) && !sourceRebuildTask.getId().equals(checkcheckNameResult.getId())) { | ||||
|             throw new RuntimeException("以"+sourceRebuildTask.getTaskName()+"为名称的任务已存在"); | ||||
|         } | ||||
|         checkIdResult.setTaskName(sourceRebuildTask.getTaskName()); | ||||
|         checkIdResult.setLatmin(sourceRebuildTask.getLatmin()); | ||||
|         checkIdResult.setLonmin(sourceRebuildTask.getLonmin()); | ||||
|         checkIdResult.setLatmax(sourceRebuildTask.getLatmax()); | ||||
|         checkIdResult.setLonmax(sourceRebuildTask.getLonmax()); | ||||
|         checkIdResult.setResolution(sourceRebuildTask.getResolution()); | ||||
|         checkIdResult.setSrsStartTime(sourceRebuildTask.getSrsStartTime()); | ||||
|         checkIdResult.setSrsEndTime(sourceRebuildTask.getSrsEndTime()); | ||||
|         checkIdResult.setReleaseType(sourceRebuildTask.getReleaseType()); | ||||
|         checkIdResult.setReleaseSourceLocation(sourceRebuildTask.getReleaseSourceLocation()); | ||||
|         checkIdResult.setSourceLon(sourceRebuildTask.getSourceLon()); | ||||
|         checkIdResult.setSourceLat(sourceRebuildTask.getSourceLat()); | ||||
|         checkIdResult.setReleaseStartTime(sourceRebuildTask.getReleaseStartTime()); | ||||
|         checkIdResult.setReleaseEndTime(sourceRebuildTask.getReleaseEndTime()); | ||||
|         checkIdResult.setSourceStrength(sourceRebuildTask.getSourceStrength()); | ||||
|         checkIdResult.setHalflife(sourceRebuildTask.getHalflife()); | ||||
|         checkIdResult.setQmin(sourceRebuildTask.getQmin()); | ||||
|         checkIdResult.setQmax(sourceRebuildTask.getQmax()); | ||||
|         this.updateById(checkIdResult); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 删除源项重建任务 | ||||
|      * @param id | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void delete(Integer id) { | ||||
|         SourceRebuildTask sourceRebuildTask = this.baseMapper.selectById(id); | ||||
|         if (Objects.isNull(sourceRebuildTask)) { | ||||
|             throw new RuntimeException("此任务不存在"); | ||||
|         } | ||||
|         //删除结果文件 | ||||
|         StringBuilder outputPath = new StringBuilder(); | ||||
|         outputPath.append(systemStorageProperties.getRootPath()); | ||||
|         outputPath.append("/"); | ||||
|         outputPath.append(systemStorageProperties.getROutput()); | ||||
|         outputPath.append("/"); | ||||
|         outputPath.append(sourceRebuildTask.getTaskName()); | ||||
|         if(FileUtil.exist(outputPath.toString())){ | ||||
|             FileUtil.del(outputPath.toString()); | ||||
|         } | ||||
|         //删除日志及上传的监测数据 | ||||
|         this.sourceRebuildTaskLogService.delete(id); | ||||
|         this.monitoringDataService.delete(id); | ||||
|         this.baseMapper.deleteById(id); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 运行任务 | ||||
|      * @param id | ||||
|      */ | ||||
|     @Override | ||||
|     public void runTask(Integer id) { | ||||
|         SourceRebuildTask sourceRebuildTask = this.baseMapper.selectById(id); | ||||
|         if(Objects.isNull(sourceRebuildTask)){ | ||||
|             throw new RuntimeException("此任务不存在"); | ||||
|         } | ||||
| 
 | ||||
|         //校验监测数据 | ||||
|         List<SourceRebuildMonitoringData> taskMonitoringDatas = this.monitoringDataService.getTaskMonitoringData(id); | ||||
|         if(CollectionUtils.isEmpty(taskMonitoringDatas)){ | ||||
|             throw new RuntimeException("监测数据为空,请补充监测数据"); | ||||
|         } | ||||
| 
 | ||||
|         SourceRebuildTaskExec sourceRebuildTaskExec = new SourceRebuildTaskExec(); | ||||
|         sourceRebuildTaskExec.init( | ||||
|                 systemStorageProperties, | ||||
|                 taskMonitoringDatas, | ||||
|                 sourceRebuildTask, | ||||
|                 sourceRebuildTaskLogService, | ||||
|                 sourceRebuildParams,this); | ||||
|         sourceRebuildTaskExec.setName(sourceRebuildTask.getId()+"_任务执行线程"); | ||||
|         sourceRebuildTaskExec.start(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取任务运行日志 | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     @Override | ||||
|     public List<SourceRebuildTaskLog> getTaskLog(Integer taskId) { | ||||
|         LambdaQueryWrapper<SourceRebuildTaskLog> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(SourceRebuildTaskLog::getTaskId, taskId); | ||||
|         queryWrapper.select(SourceRebuildTaskLog::getCreateTime,SourceRebuildTaskLog::getLogContent); | ||||
|         return sourceRebuildTaskLogMapper.selectList(queryWrapper); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 修改任务状态 | ||||
|      * | ||||
|      * @param taskId | ||||
|      * @param taskStatus | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void updateTaskStatus(Integer taskId, Integer taskStatus) { | ||||
|         SourceRebuildTask sourceRebuildTask = this.baseMapper.selectById(taskId); | ||||
|         sourceRebuildTask.setTaskStatus(taskStatus); | ||||
|         this.updateById(sourceRebuildTask); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 任务耗时 | ||||
|      * | ||||
|      * @param taskId | ||||
|      * @param taskTimeConsuming | ||||
|      */ | ||||
|     @Transactional(rollbackFor = RuntimeException.class) | ||||
|     @Override | ||||
|     public void updateTaskTimeConsuming(Integer taskId, Integer taskTimeConsuming) { | ||||
|         SourceRebuildTask sourceRebuildTask = this.baseMapper.selectById(taskId); | ||||
|         sourceRebuildTask.setTimeConsuming(taskTimeConsuming); | ||||
|         this.updateById(sourceRebuildTask); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,512 @@ | |||
| package org.jeecg.service.impl; | ||||
| 
 | ||||
| import cn.hutool.core.date.DateUtil; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.jeecg.common.properties.SourceRebuildParams; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTask; | ||||
| import org.jeecg.service.SourceRebuildTaskService; | ||||
| import org.jeecg.service.TaskResultDataService; | ||||
| import org.jeecg.vo.*; | ||||
| import org.rosuda.REngine.REXP; | ||||
| import org.rosuda.REngine.REXPMismatchException; | ||||
| import org.rosuda.REngine.RList; | ||||
| import org.rosuda.REngine.Rserve.RConnection; | ||||
| import org.rosuda.REngine.Rserve.RserveException; | ||||
| import org.springframework.stereotype.Service; | ||||
| 
 | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.*; | ||||
| 
 | ||||
| @Service | ||||
| @RequiredArgsConstructor | ||||
| public class TaskResultDataServiceImpl implements TaskResultDataService { | ||||
| 
 | ||||
|     private final SourceRebuildTaskService sourceRebuildTaskService; | ||||
|     private final SourceRebuildParams sourceRebuildParams; | ||||
| 
 | ||||
|     /** | ||||
|      * 获取Rserve连接 | ||||
|      * @return | ||||
|      */ | ||||
|     private RConnection getRConnection(){ | ||||
|         RConnection conn = null; | ||||
|         try { | ||||
|             conn = new RConnection(sourceRebuildParams.getServerAddr(),sourceRebuildParams.getPort()); | ||||
|             conn.login(sourceRebuildParams.getUsername(), sourceRebuildParams.getPassword()); | ||||
|         } catch (RserveException e) { | ||||
|             throw new RuntimeException("Rserve连接失败"); | ||||
|         } | ||||
|         return conn; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 关闭Rserve连接 | ||||
|      * @param connection | ||||
|      */ | ||||
|     private void closeRConnection(RConnection connection){ | ||||
|         if(Objects.nonNull(connection) && connection.isConnected()){ | ||||
|             connection.close(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     @Override | ||||
|     public SourceProbabilityGrid getBayesProbLoc(Integer taskId) { | ||||
|         SourceRebuildTask task = this.sourceRebuildTaskService.getById(taskId); | ||||
|         if(StringUtils.isBlank(task.getResultAddress())){ | ||||
|             throw new RuntimeException("此任务运行结果不存在,请检查运行日志"); | ||||
|         } | ||||
|         RConnection conn = this.getRConnection(); | ||||
|         if(!conn.isConnected()){ | ||||
|             throw new RuntimeException("Rserve连接不可用"); | ||||
|         } | ||||
|         SourceProbabilityGrid sourceProbabilityGrid =  new SourceProbabilityGrid(); | ||||
|         try { | ||||
|             String rdsPath = task.getResultAddress()+"/probloc.RDS"; | ||||
|             REXP result = conn.eval("readRDS('" + rdsPath + "')"); | ||||
|             if (result.isNumeric()) { | ||||
|                 sourceProbabilityGrid.setData(result.asDoubleMatrix()); | ||||
|                 sourceProbabilityGrid.setLonmin(task.getLonmin()); | ||||
|                 sourceProbabilityGrid.setLonmax(task.getLonmax()); | ||||
|                 sourceProbabilityGrid.setLatmin(task.getLatmin()); | ||||
|                 sourceProbabilityGrid.setLatmax(task.getLatmax()); | ||||
|                 sourceProbabilityGrid.setRows(result.asDoubleMatrix().length); | ||||
|                 sourceProbabilityGrid.setCols(result.asDoubleMatrix()[0].length); | ||||
|             } | ||||
|         } catch (RserveException e) { | ||||
|             throw new RuntimeException("RDS读取异常",e); | ||||
|         } catch (REXPMismatchException e) { | ||||
|             throw new RuntimeException("概率图矩阵数据解析异常",e); | ||||
|         }finally { | ||||
|             this.closeRConnection(conn); | ||||
|         } | ||||
|         return sourceProbabilityGrid; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取观测值和模拟值的活度浓度比较结果数据 | ||||
|      * @param taskId | ||||
|      * @return | ||||
|      */ | ||||
|     @Override | ||||
|     public ActivityConcComparResult getBayesAcTimeSeries(Integer taskId) { | ||||
|         SourceRebuildTask task = this.sourceRebuildTaskService.getById(taskId); | ||||
|         if(StringUtils.isBlank(task.getResultAddress())){ | ||||
|             throw new RuntimeException("此任务运行结果不存在,请检查运行日志"); | ||||
|         } | ||||
|         RConnection conn = this.getRConnection(); | ||||
|         if(!conn.isConnected()){ | ||||
|             throw new RuntimeException("Rserve连接不可用"); | ||||
|         } | ||||
|         ActivityConcComparResult activityConcComparResult =  new ActivityConcComparResult(); | ||||
|         try { | ||||
|             String obsRdsPath = task.getResultAddress()+"/obs.RDS"; | ||||
|             REXP obsResult = conn.eval("readRDS('" + obsRdsPath + "')"); | ||||
|             if (obsResult.isNumeric()) { | ||||
|                 activityConcComparResult.setObsValues(obsResult.asDoubles()); | ||||
|             } | ||||
|             String modRdsPath = task.getResultAddress()+"/mod.RDS"; | ||||
|             REXP modResult = conn.eval("readRDS('" + modRdsPath + "')"); | ||||
|             if (modResult.isNumeric()) { | ||||
|                 activityConcComparResult.setModValues(modResult.asDoubles()); | ||||
|             } | ||||
|             String mdcRdsPath = task.getResultAddress()+"/MDC.RDS"; | ||||
|             REXP mdcResult = conn.eval("readRDS('" + mdcRdsPath + "')"); | ||||
|             if (mdcResult.isNumeric()) { | ||||
|                 activityConcComparResult.setMdcValues(mdcResult.asDoubles()); | ||||
|             } | ||||
|             String stationsTxtPath = task.getResultAddress()+"/statnames.txt"; | ||||
|             REXP stationsResult = conn.eval("readLines('" + stationsTxtPath + "')"); | ||||
|             if (stationsResult.isString()) { | ||||
|                 activityConcComparResult.setStations(stationsResult.asStrings()); | ||||
|             } | ||||
|         } catch (RserveException e) { | ||||
|             throw new RuntimeException("RDS读取异常",e); | ||||
|         } catch (REXPMismatchException e) { | ||||
|             throw new RuntimeException("概率图矩阵数据解析异常",e); | ||||
|         }finally { | ||||
|             this.closeRConnection(conn); | ||||
|         } | ||||
|         return activityConcComparResult; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取双变量后验分布 | ||||
|      * | ||||
|      * @param taskId | ||||
|      */ | ||||
|     @Override | ||||
|     public void getBayesBivarPosterior(Integer taskId) { | ||||
|         SourceRebuildTask task = this.sourceRebuildTaskService.getById(taskId); | ||||
|         if(StringUtils.isBlank(task.getResultAddress())){ | ||||
|             throw new RuntimeException("此任务运行结果不存在,请检查运行日志"); | ||||
|         } | ||||
|         RConnection conn = this.getRConnection(); | ||||
|         if(!conn.isConnected()){ | ||||
|             throw new RuntimeException("Rserve连接不可用"); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取单变量后验分布 | ||||
|      * | ||||
|      * @param taskId | ||||
|      */ | ||||
|     @Override | ||||
|     public Map<String,Object> getBayesMonovarPosterior(Integer taskId) { | ||||
|         SourceRebuildTask task = this.sourceRebuildTaskService.getById(taskId); | ||||
|         if(StringUtils.isBlank(task.getResultAddress())){ | ||||
|             throw new RuntimeException("此任务运行结果不存在,请检查运行日志"); | ||||
|         } | ||||
|         RConnection conn = this.getRConnection(); | ||||
|         if(!conn.isConnected()){ | ||||
|             throw new RuntimeException("Rserve连接不可用"); | ||||
|         } | ||||
|         Map<String,Object> result = new HashMap<>(); | ||||
|         try { | ||||
|             String posteriorRdsPath = task.getResultAddress()+"/bayes_monovarPosterior_aux.RDS"; | ||||
|             REXP posteriorResult = conn.eval("readRDS('" + posteriorRdsPath + "')"); | ||||
|             if (posteriorResult.isList()) { | ||||
|                 //list是一个列表,拥有chaindf, post_median, breaks, zprior多个嵌套对象 | ||||
|                 RList list = posteriorResult.asList(); | ||||
|                 //chaindf,它是一个R的DataFrame,存储的是抽样数据 | ||||
|                 REXP chaindf = list.at("chaindf"); | ||||
|                 //trueValues存储的是已知的释放源信息 | ||||
|                 //REXP trueValues = list.at("trueValues"); | ||||
|                 //存储的是lon、lat、log10_Q、tstart、tstop的中位数 | ||||
|                 REXP post_median = list.at("post_median"); | ||||
|                 //存储的是lon、lat、log10_Q、tstart、tstop的X轴的边界数据 | ||||
|                 REXP breaks = list.at("breaks"); | ||||
|                 //先验密度(在 breaks 点上) | ||||
|                 REXP zprior = list.at("zprior"); | ||||
|                 Map<String, Object> lonChartDataMap = this.processLonChart(chaindf, post_median, breaks, zprior); | ||||
|                 Map<String, Object> latChartDataMap = this.processLatChart(chaindf, post_median, breaks, zprior); | ||||
|                 Map<String, Object> log10ChartDataMap = this.processLog10Chart(chaindf, post_median, breaks, zprior); | ||||
|                 Map<String, Object> startChartDataMap = this.processStartChart(chaindf, post_median, breaks, zprior); | ||||
|                 Map<String, Object> stopChartDataMap = this.processStopChart(chaindf, post_median, breaks, zprior); | ||||
|                 result.putAll(lonChartDataMap); | ||||
|                 result.putAll(latChartDataMap); | ||||
|                 result.putAll(log10ChartDataMap); | ||||
|                 result.putAll(startChartDataMap); | ||||
|                 result.putAll(stopChartDataMap); | ||||
|             } | ||||
|         } catch (RserveException e) { | ||||
|             throw new RuntimeException("RDS读取异常",e); | ||||
|         } catch (REXPMismatchException e) { | ||||
|             throw new RuntimeException("RDS 文件不是一个列表结构",e); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 处理lon图表数据 | ||||
|      * @param chaindf | ||||
|      * @param postMedian | ||||
|      * @param breaks | ||||
|      * @param zprior | ||||
|      * @return | ||||
|      */ | ||||
|     private Map<String,Object> processLonChart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { | ||||
|         Map<String,Object> map = new HashMap<>(); | ||||
|         //封装对象 | ||||
|         HistogramChartStru histogramChartStru = new HistogramChartStru(); | ||||
|         //设置中位数(蓝色线) | ||||
|         REXP lon = postMedian.asList().at("lon"); | ||||
|         histogramChartStru.setPostMedian(lon.asDouble()); | ||||
|         //设置先验分布数据(绿色线) | ||||
|         REXP break1 = breaks.asList().at(0); | ||||
|         if(break1.isNumeric() && zprior.isNumeric()){ | ||||
|             double[] break1Data = break1.asDoubles(); | ||||
|             double[][] zprio1Data = zprior.asDoubleMatrix(); | ||||
|             //设置X轴边界 | ||||
|             histogramChartStru.setXMin(break1Data[0]); | ||||
|             histogramChartStru.setXMax(break1Data[break1Data.length-1]); | ||||
|             if(break1Data.length != zprio1Data.length){ | ||||
|                 throw new RuntimeException("RDS读取异常,break数据和zprio长度不一致"); | ||||
|             } | ||||
|             List<PriorDistribution> priorDistributionList =  new ArrayList<>(); | ||||
|             for (int i = 0; i < break1Data.length; i++) { | ||||
|                 PriorDistribution priorDistribution = new PriorDistribution(); | ||||
|                 priorDistribution.setXValue(break1Data[i]); | ||||
|                 priorDistribution.setYValue(zprio1Data[i][0]); | ||||
|                 priorDistributionList.add(priorDistribution); | ||||
|             } | ||||
|             histogramChartStru.setPriorDistributionList(priorDistributionList); | ||||
|         } | ||||
|         //获取lon列数据 | ||||
|         REXP column = chaindf.asList().at(0); | ||||
|         if(column.isNumeric()){ | ||||
|             double[] break1Data = break1.asDoubles(); | ||||
|             double[] columnVals = column.asDoubles(); | ||||
|             List<HistogramChartBarData> histogramChartBarDataList =  new ArrayList<>(); | ||||
|             for (int i= 0; i < break1Data.length; i++) { | ||||
|                 if(i==break1Data.length-1){ | ||||
|                     break; | ||||
|                 } | ||||
|                 int finalI = i; | ||||
|                 long countVal = Arrays.stream(columnVals).parallel().filter(colVals -> (colVals >= break1Data[finalI] && colVals <= break1Data[finalI + 1])).count(); | ||||
|                 HistogramChartBarData histogramChartBarData = new HistogramChartBarData(); | ||||
|                 histogramChartBarData.setXLeftVal(break1Data[i]); | ||||
|                 histogramChartBarData.setXRightVal(break1Data[i+1]); | ||||
|                 histogramChartBarData.setYValue(countVal); | ||||
|                 histogramChartBarDataList.add(histogramChartBarData); | ||||
|             } | ||||
|             histogramChartStru.setHistogramChartBarDataList(histogramChartBarDataList); | ||||
|         } | ||||
|         map.put("lonChartStru",histogramChartStru); | ||||
|         return map; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 处理lat图表数据 | ||||
|      * @param chaindf | ||||
|      * @param postMedian | ||||
|      * @param breaks | ||||
|      * @param zprior | ||||
|      * @return | ||||
|      */ | ||||
|     private Map<String,Object> processLatChart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { | ||||
|         Map<String,Object> map = new HashMap<>(); | ||||
|         //封装对象 | ||||
|         HistogramChartStru histogramChartStru = new HistogramChartStru(); | ||||
|         //设置中位数(蓝色线) | ||||
|         REXP lat = postMedian.asList().at("lat"); | ||||
|         histogramChartStru.setPostMedian(lat.asDouble()); | ||||
|         //设置先验分布数据(绿色线) | ||||
|         REXP break2 = breaks.asList().at(1); | ||||
|         if(break2.isNumeric() && zprior.isNumeric()){ | ||||
|             double[] break2Data = break2.asDoubles(); | ||||
|             double[][] zprio2Data = zprior.asDoubleMatrix(); | ||||
|             //设置X轴边界 | ||||
|             histogramChartStru.setXMin(break2Data[0]); | ||||
|             histogramChartStru.setXMax(break2Data[break2Data.length-1]); | ||||
|             if(break2Data.length != zprio2Data.length){ | ||||
|                 throw new RuntimeException("RDS读取异常,break数据和zprio长度不一致"); | ||||
|             } | ||||
|             List<PriorDistribution> priorDistributionList =  new ArrayList<>(); | ||||
|             for (int i = 0; i < break2Data.length; i++) { | ||||
|                 PriorDistribution priorDistribution = new PriorDistribution(); | ||||
|                 priorDistribution.setXValue(break2Data[i]); | ||||
|                 priorDistribution.setYValue(zprio2Data[i][1]); | ||||
|                 priorDistributionList.add(priorDistribution); | ||||
|             } | ||||
|             histogramChartStru.setPriorDistributionList(priorDistributionList); | ||||
|         } | ||||
|         //获取lat列数据 | ||||
|         REXP column = chaindf.asList().at(1); | ||||
|         if(column.isNumeric()){ | ||||
|             double[] break1Data = break2.asDoubles(); | ||||
|             double[] columnVals = column.asDoubles(); | ||||
|             List<HistogramChartBarData> histogramChartBarDataList =  new ArrayList<>(); | ||||
|             for (int i= 0; i < break1Data.length; i++) { | ||||
|                 if(i==break1Data.length-1){ | ||||
|                     break; | ||||
|                 } | ||||
|                 int finalI = i; | ||||
|                 long countVal = Arrays.stream(columnVals).parallel().filter(colVals -> (colVals >= break1Data[finalI] && colVals <= break1Data[finalI + 1])).count(); | ||||
|                 HistogramChartBarData histogramChartBarData = new HistogramChartBarData(); | ||||
|                 histogramChartBarData.setXLeftVal(break1Data[i]); | ||||
|                 histogramChartBarData.setXRightVal(break1Data[i+1]); | ||||
|                 histogramChartBarData.setYValue(countVal); | ||||
|                 histogramChartBarDataList.add(histogramChartBarData); | ||||
|             } | ||||
|             histogramChartStru.setHistogramChartBarDataList(histogramChartBarDataList); | ||||
|         } | ||||
|         map.put("latChartStru",histogramChartStru); | ||||
|         return map; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 处理log10_Q图表数据 | ||||
|      * @param chaindf | ||||
|      * @param postMedian | ||||
|      * @param breaks | ||||
|      * @param zprior | ||||
|      * @return | ||||
|      */ | ||||
|     private Map<String,Object> processLog10Chart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { | ||||
|         Map<String,Object> map = new HashMap<>(); | ||||
|         //封装对象 | ||||
|         HistogramChartStru histogramChartStru = new HistogramChartStru(); | ||||
|         //设置中位数(蓝色线) | ||||
|         REXP log10_Q = postMedian.asList().at("log10_Q"); | ||||
|         histogramChartStru.setPostMedian(log10_Q.asDouble()); | ||||
|         //设置先验分布数据(绿色线) | ||||
|         REXP break3 = breaks.asList().at(2); | ||||
|         if(break3.isNumeric() && zprior.isNumeric()){ | ||||
|             double[] break3Data = break3.asDoubles(); | ||||
|             double[][] zprio3Data = zprior.asDoubleMatrix(); | ||||
|             //设置X轴边界 | ||||
|             histogramChartStru.setXMin(break3Data[0]); | ||||
|             histogramChartStru.setXMax(break3Data[break3Data.length-1]); | ||||
|             if(break3Data.length != zprio3Data.length){ | ||||
|                 throw new RuntimeException("RDS读取异常,break数据和zprio长度不一致"); | ||||
|             } | ||||
|             List<PriorDistribution> priorDistributionList =  new ArrayList<>(); | ||||
|             for (int i = 0; i < break3Data.length; i++) { | ||||
|                 PriorDistribution priorDistribution = new PriorDistribution(); | ||||
|                 priorDistribution.setXValue(break3Data[i]); | ||||
|                 priorDistribution.setYValue(zprio3Data[i][2]); | ||||
|                 priorDistributionList.add(priorDistribution); | ||||
|             } | ||||
|             histogramChartStru.setPriorDistributionList(priorDistributionList); | ||||
|         } | ||||
|         //获取log10_Q列数据 | ||||
|         REXP column = chaindf.asList().at(2); | ||||
|         if(column.isNumeric()){ | ||||
|             double[] break1Data = break3.asDoubles(); | ||||
|             double[] columnVals = column.asDoubles(); | ||||
|             List<HistogramChartBarData> histogramChartBarDataList =  new ArrayList<>(); | ||||
|             for (int i= 0; i < break1Data.length; i++) { | ||||
|                 if(i==break1Data.length-1){ | ||||
|                     break; | ||||
|                 } | ||||
|                 int finalI = i; | ||||
|                 long countVal = Arrays.stream(columnVals).parallel().filter(colVals -> (colVals >= break1Data[finalI] && colVals <= break1Data[finalI + 1])).count(); | ||||
|                 HistogramChartBarData histogramChartBarData = new HistogramChartBarData(); | ||||
|                 histogramChartBarData.setXLeftVal(break1Data[i]); | ||||
|                 histogramChartBarData.setXRightVal(break1Data[i+1]); | ||||
|                 histogramChartBarData.setYValue(countVal); | ||||
|                 histogramChartBarDataList.add(histogramChartBarData); | ||||
|             } | ||||
|             histogramChartStru.setHistogramChartBarDataList(histogramChartBarDataList); | ||||
|         } | ||||
|         map.put("log10_QChartStru",histogramChartStru); | ||||
|         return map; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 处理tstart图表数据 | ||||
|      * @param chaindf | ||||
|      * @param postMedian | ||||
|      * @param breaks | ||||
|      * @param zprior | ||||
|      * @return | ||||
|      */ | ||||
|     private Map<String,Object> processStartChart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { | ||||
|         Map<String,Object> map = new HashMap<>(); | ||||
|         //封装对象 | ||||
|         HistogramChartStru histogramChartStru = new HistogramChartStru(); | ||||
|         //设置中位数(蓝色线) | ||||
|         REXP tstart = postMedian.asList().at("rstart"); | ||||
|         histogramChartStru.setPostMedian(this.posixctToCSTString(tstart.asDouble())); | ||||
|         //设置先验分布数据(绿色线) | ||||
|         REXP break4 = breaks.asList().at(3); | ||||
|         if(break4.isNumeric() && zprior.isNumeric()){ | ||||
|             double[] break4Data = break4.asDoubles(); | ||||
|             double[][] zprio4Data = zprior.asDoubleMatrix(); | ||||
|             //设置X轴边界 | ||||
|             histogramChartStru.setXMin(this.posixctToCSTString(break4Data[0])); | ||||
|             histogramChartStru.setXMax(this.posixctToCSTString(break4Data[break4Data.length-1])); | ||||
|             if(break4Data.length != zprio4Data.length){ | ||||
|                 throw new RuntimeException("RDS读取异常,break数据和zprio长度不一致"); | ||||
|             } | ||||
|             List<PriorDistribution> priorDistributionList =  new ArrayList<>(); | ||||
|             for (int i = 0; i < break4Data.length; i++) { | ||||
|                 PriorDistribution priorDistribution = new PriorDistribution(); | ||||
|                 priorDistribution.setXValue(this.posixctToCSTString(break4Data[i])); | ||||
|                 priorDistribution.setYValue(String.format("%.20f",zprio4Data[i][3])); | ||||
|                 priorDistributionList.add(priorDistribution); | ||||
|             } | ||||
|             histogramChartStru.setPriorDistributionList(priorDistributionList); | ||||
|         } | ||||
|         //获取tstart列数据 | ||||
|         REXP column = chaindf.asList().at(3); | ||||
|         if(column.isNumeric()){ | ||||
|             double[] break1Data = break4.asDoubles(); | ||||
|             double[] columnVals = column.asDoubles(); | ||||
|             List<HistogramChartBarData> histogramChartBarDataList =  new ArrayList<>(); | ||||
|             for (int i= 0; i < break1Data.length; i++) { | ||||
|                 if(i==break1Data.length-1){ | ||||
|                     break; | ||||
|                 } | ||||
|                 int finalI = i; | ||||
|                 long countVal = Arrays.stream(columnVals).parallel().filter(colVals -> (colVals >= break1Data[finalI] && colVals <= break1Data[finalI + 1])).count(); | ||||
|                 HistogramChartBarData histogramChartBarData = new HistogramChartBarData(); | ||||
|                 histogramChartBarData.setXLeftVal(this.posixctToCSTString(break1Data[i])); | ||||
|                 histogramChartBarData.setXRightVal(this.posixctToCSTString(break1Data[i+1])); | ||||
|                 histogramChartBarData.setYValue(countVal); | ||||
|                 histogramChartBarDataList.add(histogramChartBarData); | ||||
|             } | ||||
|             histogramChartStru.setHistogramChartBarDataList(histogramChartBarDataList); | ||||
|         } | ||||
|         map.put("startChartStru",histogramChartStru); | ||||
|         return map; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 处理tstop图表数据 | ||||
|      * @param chaindf | ||||
|      * @param postMedian | ||||
|      * @param breaks | ||||
|      * @param zprior | ||||
|      * @return | ||||
|      */ | ||||
|     private Map<String,Object> processStopChart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { | ||||
|         Map<String,Object> map = new HashMap<>(); | ||||
|         //封装对象 | ||||
|         HistogramChartStru histogramChartStru = new HistogramChartStru(); | ||||
|         //设置中位数(蓝色线) | ||||
|         REXP tstart = postMedian.asList().at("rstop"); | ||||
|         histogramChartStru.setPostMedian(this.posixctToCSTString(tstart.asDouble())); | ||||
|         //设置先验分布数据(绿色线) | ||||
|         REXP break5 = breaks.asList().at(4); | ||||
|         if(break5.isNumeric() && zprior.isNumeric()){ | ||||
|             double[] break5Data = break5.asDoubles(); | ||||
|             double[][] zprio5Data = zprior.asDoubleMatrix(); | ||||
|             //设置X轴边界 | ||||
|             histogramChartStru.setXMin(this.posixctToCSTString(break5Data[0])); | ||||
|             histogramChartStru.setXMax(this.posixctToCSTString(break5Data[break5Data.length-1])); | ||||
|             if(break5Data.length != zprio5Data.length){ | ||||
|                 throw new RuntimeException("RDS读取异常,break数据和zprio长度不一致"); | ||||
|             } | ||||
|             List<PriorDistribution> priorDistributionList =  new ArrayList<>(); | ||||
|             for (int i = 0; i < break5Data.length; i++) { | ||||
|                 PriorDistribution priorDistribution = new PriorDistribution(); | ||||
|                 priorDistribution.setXValue(this.posixctToCSTString(break5Data[i])); | ||||
|                 priorDistribution.setYValue(String.format("%.20f",zprio5Data[i][4])); | ||||
|                 priorDistributionList.add(priorDistribution); | ||||
|             } | ||||
|             histogramChartStru.setPriorDistributionList(priorDistributionList); | ||||
|         } | ||||
|         //获取tstop列数据 | ||||
|         REXP column = chaindf.asList().at(4); | ||||
|         if(column.isNumeric()){ | ||||
|             double[] break1Data = break5.asDoubles(); | ||||
|             double[] columnVals = column.asDoubles(); | ||||
|             List<HistogramChartBarData> histogramChartBarDataList =  new ArrayList<>(); | ||||
|             for (int i= 0; i < break1Data.length; i++) { | ||||
|                 if(i==break1Data.length-1){ | ||||
|                     break; | ||||
|                 } | ||||
|                 int finalI = i; | ||||
|                 long countVal = Arrays.stream(columnVals).parallel().filter(colVals -> (colVals >= break1Data[finalI] && colVals <= break1Data[finalI + 1])).count(); | ||||
|                 HistogramChartBarData histogramChartBarData = new HistogramChartBarData(); | ||||
|                 histogramChartBarData.setXLeftVal(this.posixctToCSTString(break1Data[i])); | ||||
|                 histogramChartBarData.setXRightVal(this.posixctToCSTString(break1Data[i+1])); | ||||
|                 histogramChartBarData.setYValue(countVal); | ||||
|                 histogramChartBarDataList.add(histogramChartBarData); | ||||
|             } | ||||
|             histogramChartStru.setHistogramChartBarDataList(histogramChartBarDataList); | ||||
|         } | ||||
|         map.put("stopChartStru",histogramChartStru); | ||||
|         return map; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 转换R语言项目的时间 | ||||
|      * @param posixctSeconds | ||||
|      * @return | ||||
|      */ | ||||
|     private String posixctToCSTString(double posixctSeconds){ | ||||
|         Date date = new Date((long) posixctSeconds * 1000); | ||||
|         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||||
|         sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); | ||||
|         return sdf.format(date); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,386 @@ | |||
| package org.jeecg.task; | ||||
| 
 | ||||
| import cn.hutool.core.date.DateUtil; | ||||
| import cn.hutool.core.io.FileUtil; | ||||
| import cn.hutool.core.util.ArrayUtil; | ||||
| import org.apache.commons.lang3.time.StopWatch; | ||||
| import org.jeecg.common.constant.enums.SourceRebuildReleaseSourceEnum; | ||||
| import org.jeecg.common.constant.enums.SourceRebuildTaskStatusEnum; | ||||
| import org.jeecg.common.properties.SourceRebuildParams; | ||||
| import org.jeecg.common.properties.SystemStorageProperties; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildMonitoringData; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTask; | ||||
| import org.jeecg.modules.base.entity.SourceRebuildTaskLog; | ||||
| import org.jeecg.service.SourceRebuildTaskLogService; | ||||
| import org.jeecg.service.SourceRebuildTaskService; | ||||
| import org.rosuda.REngine.REXP; | ||||
| import org.rosuda.REngine.REXPDouble; | ||||
| import org.rosuda.REngine.REXPInteger; | ||||
| import org.rosuda.REngine.REXPMismatchException; | ||||
| import org.rosuda.REngine.Rserve.RConnection; | ||||
| import org.rosuda.REngine.Rserve.RserveException; | ||||
| import org.springframework.util.CollectionUtils; | ||||
| import java.io.File; | ||||
| import java.math.BigDecimal; | ||||
| import java.math.RoundingMode; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.text.DecimalFormat; | ||||
| import java.util.*; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import java.util.stream.Stream; | ||||
| 
 | ||||
| public class SourceRebuildTaskExec extends Thread{ | ||||
| 
 | ||||
|     private SystemStorageProperties systemStorageProperties; | ||||
|     private List<SourceRebuildMonitoringData> taskMonitoringDatas; | ||||
|     private SourceRebuildTaskLogService sourceRebuildTaskLogService; | ||||
|     private SourceRebuildTask sourceRebuildTask; | ||||
|     private SourceRebuildParams sourceRebuildParams; | ||||
|     private SourceRebuildTaskService sourceRebuildTaskService; | ||||
| 
 | ||||
|     /** | ||||
|      * 初始化 | ||||
|      */ | ||||
|     public void init(SystemStorageProperties systemStorageProperties, | ||||
|                      List<SourceRebuildMonitoringData> taskMonitoringDatas, | ||||
|                      SourceRebuildTask sourceRebuildTask, | ||||
|                      SourceRebuildTaskLogService sourceRebuildTaskLogService, | ||||
|                      SourceRebuildParams sourceRebuildParams, | ||||
|                      SourceRebuildTaskService sourceRebuildTaskService){ | ||||
|         this.systemStorageProperties = systemStorageProperties; | ||||
|         this.taskMonitoringDatas = taskMonitoringDatas; | ||||
|         this.sourceRebuildTask = sourceRebuildTask; | ||||
|         this.sourceRebuildTaskLogService = sourceRebuildTaskLogService; | ||||
|         this.sourceRebuildParams = sourceRebuildParams; | ||||
|         this.sourceRebuildTaskService = sourceRebuildTaskService; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void run() { | ||||
|         this.execute(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 执行任务 | ||||
|      */ | ||||
|     public void execute(){ | ||||
|         StopWatch  stopWatch = new StopWatch(); | ||||
|         stopWatch.start(); | ||||
|         try{ | ||||
|             //修改任务状态为执行中 | ||||
|             this.sourceRebuildTaskService.updateTaskStatus(this.sourceRebuildTask.getId(), SourceRebuildTaskStatusEnum.IN_OPERATION.getValue()); | ||||
|             //如果此任务已存在历史日志,先清除 | ||||
|             sourceRebuildTaskLogService.delete(this.sourceRebuildTask.getId()); | ||||
|             String startRunLog = "----------------------------------------开始执行任务----------------------------------------"; | ||||
|             this.generateLog(startRunLog); | ||||
|             //生成重建需要的监测数据 | ||||
|             String monitorDataLog = "----------------------------------------生成监测数据输入文件----------------------------------------"; | ||||
|             String titleLog = "Entity,Metric,Date,Value,Uncertainty,MDC Value"; | ||||
|             this.generateLog(monitorDataLog); | ||||
|             this.generateLog(titleLog); | ||||
|            // this.generateMonitoringDataFile(); | ||||
|             //生成SRS关系文件 | ||||
|             String srsDataLog = "----------------------------------------生成SRS数据输入文件----------------------------------------"; | ||||
|             this.generateLog(srsDataLog); | ||||
|            // this.generateSRSDataFile(); | ||||
|             String sourceProcessDataLog = "----------------------------------------配置源项分析参数并执行源项重建----------------------------------------"; | ||||
|             this.generateLog(sourceProcessDataLog); | ||||
|             this.execSourceRebuild(); | ||||
|             String genStopLog = "----------------------------------------任务执行结束----------------------------------------"; | ||||
|             this.generateLog(genStopLog); | ||||
|         }catch (Exception e){ | ||||
|             String taskErrorLog = "任务执行失败,原因:"+e.getMessage(); | ||||
|             this.generateLog(taskErrorLog); | ||||
|             throw e; | ||||
|         }finally { | ||||
|             //添加任务耗时 | ||||
|             stopWatch.stop(); | ||||
|             Integer time = Long.valueOf(stopWatch.getTime(TimeUnit.MINUTES)).intValue(); | ||||
|             this.sourceRebuildTaskService.updateTaskTimeConsuming(this.sourceRebuildTask.getId(),time); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 生成重建需要的监测数据 | ||||
|      */ | ||||
|     private void generateMonitoringDataFile(){ | ||||
|         //根据监测数据生成文件(input_subexp1.dat) | ||||
|         String inputPath = this.getInputPath(); | ||||
|         File inputSubexp1 = new File(inputPath.toString() +File.separator+ "input_subexp1.dat"); | ||||
|         if(!FileUtil.exist(inputSubexp1)){ | ||||
|             FileUtil.touch(inputSubexp1); | ||||
|         } | ||||
|         //格式化监测数据 | ||||
|         String title = "Entity,Metric,Date,Value,Uncertainty,MDC Value"; | ||||
|         List<String> lines = new ArrayList<>(); | ||||
|         lines.add(title); | ||||
| 
 | ||||
|         for(SourceRebuildMonitoringData taskMonitoringData : taskMonitoringDatas){ | ||||
|             String station = taskMonitoringData.getStation(); | ||||
|             String nuclide = taskMonitoringData.getNuclide(); | ||||
|             String date = DateUtil.format(taskMonitoringData.getCollectStop(),"yyyy-MM-dd HH:mm"); | ||||
|             String activity = this.formatSCI(taskMonitoringData.getActivity()); | ||||
|             String uncertainty = this.formatSCI(taskMonitoringData.getUncertainty()); | ||||
|             String mdc = this.formatSCI(taskMonitoringData.getMdc()); | ||||
| 
 | ||||
|             String formattedLine = String.format("%s, %s, %s, %s, %s, %s",station,nuclide,date,activity,uncertainty,mdc); | ||||
|             lines.add(formattedLine); | ||||
|             //把监测数据详情保存到日志 | ||||
|             this.generateLog(formattedLine); | ||||
| 
 | ||||
|         } | ||||
|         FileUtil.writeLines(lines,inputSubexp1,"UTF-8"); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 生成SRS关系数据文件 | ||||
|      */ | ||||
|     private void generateSRSDataFile(){ | ||||
|         //以日期为key,以文件相对路径为value | ||||
|         Map<Date,String> allSRSFileMap = new HashMap<>(); | ||||
|         Map<Date,String> finalSRSFileMap = new TreeMap<>(); | ||||
|         //根据监测数据校验SRS文件,如果缺少SRS文件也报错 | ||||
|         String srsFilePath = this.getSRSFilePath(); | ||||
|         Path dirpath = Paths.get(srsFilePath); | ||||
|         try(Stream<Path> walk = Files.walk(dirpath)) { | ||||
|             walk.filter(Files::isRegularFile) | ||||
|                 .filter(path -> path.toAbsolutePath().toString().contains(systemStorageProperties.getXeGZFileDirSign())) | ||||
|                 .forEach(filePath -> { | ||||
|                     //USX77.fp.2024112115.f9.srm | ||||
|                     String[] nameArr = filePath.getFileName().toString().split("\\."); | ||||
|                     Date date = DateUtil.parse(nameArr[2],"yyyyMMddHH"); | ||||
|                     String relativePath = filePath.toAbsolutePath().toString().substring(filePath.toAbsolutePath().toString().indexOf("srs")); | ||||
|                     allSRSFileMap.put(date,relativePath); | ||||
|                 }); | ||||
|             //如果遍历指定目录没有找到SRS数据文件则结束 | ||||
|             if(CollectionUtils.isEmpty(allSRSFileMap)){ | ||||
|                 String srsNotExistLog = "SRS 文件存储目录中没有SRS数据文件"; | ||||
|                 throw new RuntimeException(srsNotExistLog); | ||||
|             } | ||||
|             //根据监测数据多线程找对应的SRS数据文件,每一个没找到都写入日志 | ||||
|             int srsNotExistCount = 0; | ||||
|             for(SourceRebuildMonitoringData monitoringData : this.taskMonitoringDatas){ | ||||
|                 boolean flag = false; | ||||
|                 String station = monitoringData.getStation(); | ||||
|                 Date collectStop = monitoringData.getCollectStop(); | ||||
|                 for (Map.Entry<Date, String> entry : allSRSFileMap.entrySet()) { | ||||
|                     Date date = entry.getKey(); | ||||
|                     String srsFile = entry.getValue(); | ||||
|                     if(srsFile.contains(station)){ | ||||
|                         boolean withinSixHours = this.isWithinSixHours(collectStop, date); | ||||
|                         if (withinSixHours) { | ||||
|                             finalSRSFileMap.put(collectStop, srsFile); | ||||
|                             flag = true; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (!flag){ | ||||
|                     srsNotExistCount ++; | ||||
|                     String targetSRSNotExist = "监测数据:"+DateUtil.format(collectStop,"yyyyMMddHH")+"所对应的SRS文件不存在"; | ||||
|                     this.generateLog(targetSRSNotExist); | ||||
|                 } | ||||
|             } | ||||
|             //当监测数据都寻找完对应的SRS数据文件后,未寻找到的结果如果大于0,则结束流程,并写入日志 | ||||
|             if(srsNotExistCount > 0){ | ||||
|                 String countSRSNotExist = "共有:"+srsNotExistCount+"条监测数据,找不到对应的SRS数据文件"; | ||||
|                 this.generateLog(countSRSNotExist); | ||||
|                 throw new RuntimeException(countSRSNotExist); | ||||
|             } | ||||
|             //每条监测数据都找到SRS数据文件后生成文件(srsfilelist_subexp1.dat) | ||||
|             String inputPath = getInputPath(); | ||||
|             File srsSubexp1 = new File(inputPath +File.separator+ "srsfilelist_subexp1.dat"); | ||||
|             if(!FileUtil.exist(srsSubexp1)){ | ||||
|                 FileUtil.touch(srsSubexp1); | ||||
|             } | ||||
|             //去重并格式化监测数据 | ||||
|             List<String> lines = new ArrayList<>(finalSRSFileMap.values()); | ||||
|             //把SRS数据详情保存到日志 | ||||
|             lines.forEach(this::generateLog); | ||||
|             //写入到文件 | ||||
|             FileUtil.writeLines(lines,srsSubexp1,"UTF-8"); | ||||
|         }catch (Exception e){ | ||||
|             throw new RuntimeException(e.getMessage()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 执行源项重建 | ||||
|      */ | ||||
|     private void execSourceRebuild(){ | ||||
|         RConnection conn = null; | ||||
|         try { | ||||
|             conn = new RConnection(this.sourceRebuildParams.getServerAddr(), this.sourceRebuildParams.getPort()); | ||||
|             conn.login(this.sourceRebuildParams.getUsername(), this.sourceRebuildParams.getPassword()); | ||||
|             if(conn.isConnected()){ | ||||
|                 String log = "Rserve 连接成功,设置运行参数"; | ||||
|                 this.generateLog(log); | ||||
|                 //重建任务名称 | ||||
|                 conn.assign("experiment", "FREAR_syntheticTestCase"); | ||||
|                 //重建任务输入数据目录 | ||||
|                 conn.assign("expdir", this.getInputPath()); | ||||
|                 conn.assign("datadir", this.getSRSFilePath()); | ||||
|                 //重建任务输出数据目录 | ||||
|                 conn.assign("outbasedir", this.getOutputPath()); | ||||
|                 //数据库相关 | ||||
|                 conn.assign("dbHost", "192.168.42.54"); | ||||
|                 conn.assign("dbPort", new REXPInteger(5432)); | ||||
|                 conn.assign("dbName", "stas"); | ||||
|                 conn.assign("dbUser", "stas"); | ||||
|                 conn.assign("dbPassword", "123456"); | ||||
|                 //任务关联ID | ||||
|                 conn.assign("taskId", this.sourceRebuildTask.getId().toString()); | ||||
|                 //半衰期 | ||||
|                // conn.assign("halflife", new REXPDouble(this.sourceRebuildTask.getHalflife())); | ||||
|                 //设置最小总累积源项Bq | ||||
|                 conn.assign("Qmin", new REXPDouble(Math.pow(10, this.sourceRebuildTask.getQmin()))); | ||||
|                 //设置最大总累积源项Bq | ||||
|                 conn.assign("Qmax", new REXPDouble(Math.pow(10, this.sourceRebuildTask.getQmax()))); | ||||
|                 //重建经纬度、分辨率 | ||||
|                 Double lonmin = this.sourceRebuildTask.getLonmin(); | ||||
|                 Double latmin = this.sourceRebuildTask.getLatmin(); | ||||
|                 Double lonmax = this.sourceRebuildTask.getLonmax(); | ||||
|                 Double latmax = this.sourceRebuildTask.getLatmax(); | ||||
|                 String resolution = this.sourceRebuildTask.getResolution(); | ||||
|                 String domain = String.format("domain <- list(lonmin=%s,latmin=%s,lonmax=%s,latmax=%s,dx=%s,dy=%s)",lonmin,latmin,lonmax,latmax,resolution,resolution); | ||||
|                 conn.eval(domain); | ||||
|                 //设置时间范围 | ||||
|                 String srsStartTime = DateUtil.format(this.sourceRebuildTask.getSrsStartTime(), "yyyy-MM-dd"); | ||||
|                 String srsEndTime = DateUtil.format(this.sourceRebuildTask.getSrsEndTime(), "yyyy-MM-dd"); | ||||
|                 String times = String.format("times <- expression(seq(as.POSIXct('%s'),as.POSIXct('%s'),by=3*3600))",srsStartTime,srsEndTime); | ||||
|                 conn.eval(times); | ||||
|                 //如果已知排放源位置 | ||||
|                 if(SourceRebuildReleaseSourceEnum.KNOWN.getValue().equals(this.sourceRebuildTask.getReleaseSourceLocation())){ | ||||
|                     //已知源位置经度 | ||||
|                     Double lon = this.sourceRebuildTask.getSourceLon(); | ||||
|                     //已知源位置纬度 | ||||
|                     Double lat = this.sourceRebuildTask.getSourceLat(); | ||||
|                     //已知源位置源强 | ||||
|                     Integer sourceStrength = this.sourceRebuildTask.getSourceStrength(); | ||||
|                     //已知源位置开始时间 | ||||
|                     String releaseStartTime = DateUtil.format(this.sourceRebuildTask.getReleaseStartTime(),"yyyy-MM-dd HH:mm:ss"); | ||||
|                     //已知源结束时间 | ||||
|                     String releaseEndTime = DateUtil.format(this.sourceRebuildTask.getReleaseEndTime(),"yyyy-MM-dd HH:mm:ss"); | ||||
|                     String formattedLine = String.format("trueValues <- c(%s,%s,%s,%s,%s)",lon,lat,sourceStrength,releaseStartTime,releaseEndTime); | ||||
|                     conn.eval(formattedLine); | ||||
|                 }else { | ||||
|                     //未知源 | ||||
|                     conn.eval("trueValues <- c(NA,NA,NA,NA,NA)"); | ||||
|                 } | ||||
|                 //设置工作目录 | ||||
|                 conn.eval("setwd(\""+this.sourceRebuildParams.getWorkSpace()+"\")"); | ||||
|                 //执行脚本 | ||||
|                 conn.eval("source(\"test_case/expdir/set_up.R\")"); | ||||
|                 REXP outputREXP = conn.eval("capture.output({source(\"test_case/expdir/main.R\")})"); | ||||
|                 // 将输出作为字符串数组获取 | ||||
|                 String[] outputLines = outputREXP.asStrings(); | ||||
|                 if(ArrayUtil.isNotEmpty(outputLines)){ | ||||
|                     this.batchGenerateLog(outputLines); | ||||
|                 } | ||||
|             } | ||||
|         } catch (RserveException e) { | ||||
|             String log = "Rserve 执行过程报错,请检查配置参数"; | ||||
|             throw new RuntimeException(log); | ||||
|         } catch (REXPMismatchException e) { | ||||
|             throw new RuntimeException(e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 判断两个时间误差是否在2小时内 | ||||
|      * @param date1 | ||||
|      * @param date2 | ||||
|      * @return | ||||
|      */ | ||||
|     private boolean isWithinSixHours(Date date1, Date date2){ | ||||
|         long diffInMillis = Math.abs(date2.getTime() - date1.getTime());// 毫秒差(绝对值) | ||||
|         long sixHoursInMillis = 6 * 60 * 60 * 1000; // 6小时 | ||||
|         return diffInMillis <= sixHoursInMillis; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 格式化为科学计数法 | ||||
|      * @param value | ||||
|      * @return | ||||
|      */ | ||||
|     private String formatSCI(String value){ | ||||
|         BigDecimal divideVal = new BigDecimal("1000"); | ||||
|         BigDecimal bigDecimal = new BigDecimal(value); | ||||
|         BigDecimal result = bigDecimal.divide(divideVal,RoundingMode.HALF_UP); | ||||
|         // 设置科学计数法格式:保留6位小数 | ||||
|         DecimalFormat df = new DecimalFormat("0.######E0"); | ||||
|         df.setMaximumFractionDigits(6); // 最多6位小数 | ||||
|         df.setMinimumFractionDigits(6); // 强制补零到6位 | ||||
|         return df.format(result); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取R项目运行输入监测数据及监测数据和srs对应关系文件地址 | ||||
|      * @return | ||||
|      */ | ||||
|     private String getInputPath(){ | ||||
|         StringBuilder inputPath = new StringBuilder(); | ||||
|         inputPath.append(systemStorageProperties.getRootPath()); | ||||
|         inputPath.append("/"); | ||||
|         inputPath.append(systemStorageProperties.getRInput()); | ||||
|         if(!FileUtil.exist(inputPath.toString())){ | ||||
|             FileUtil.mkdir(inputPath.toString()); | ||||
|         } | ||||
|         return inputPath.toString(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取SRS 文件存储路径 | ||||
|      * @return | ||||
|      */ | ||||
|     private String getSRSFilePath(){ | ||||
|         StringBuilder srsFilePath = new StringBuilder(); | ||||
|         srsFilePath.append(systemStorageProperties.getRootPath()); | ||||
|         srsFilePath.append("/"); | ||||
|         srsFilePath.append(systemStorageProperties.getSrsFilePath()); | ||||
| //        if(!FileUtil.exist(srsFilePath.toString())){ | ||||
| //            String srsNotExistLog = "SRS 文件存储目录不存在"; | ||||
| //            throw new RuntimeException(srsNotExistLog); | ||||
| //        } | ||||
|         return srsFilePath.toString(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取R项目运行结果输出地址 | ||||
|      * @return | ||||
|      */ | ||||
|     private String getOutputPath(){ | ||||
|         StringBuilder outputPath = new StringBuilder(); | ||||
|         outputPath.append(systemStorageProperties.getRootPath()); | ||||
|         outputPath.append("/"); | ||||
|         outputPath.append(systemStorageProperties.getROutput()); | ||||
|         outputPath.append("/"); | ||||
|         outputPath.append(sourceRebuildTask.getTaskName()); | ||||
|         if(!FileUtil.exist(outputPath.toString())){ | ||||
|             FileUtil.mkdir(outputPath.toString()); | ||||
|         } | ||||
|         return outputPath.toString(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 保存任务运行过程日志 | ||||
|      * @param logContent | ||||
|      */ | ||||
|     private void generateLog(String logContent){ | ||||
|         sourceRebuildTaskLogService.cteate(new SourceRebuildTaskLog(sourceRebuildTask.getId(),logContent)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 保存任务运行过程日志 | ||||
|      * @param logContents | ||||
|      */ | ||||
|     private void batchGenerateLog(String[] logContents){ | ||||
|         List<SourceRebuildTaskLog> logs = new ArrayList<>(); | ||||
|         for(String logContent : logContents){ | ||||
|             logs.add(new SourceRebuildTaskLog(sourceRebuildTask.getId(),logContent)); | ||||
|         } | ||||
|         sourceRebuildTaskLogService.batchCteate(logs); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,29 @@ | |||
| package org.jeecg.vo; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 活度浓度比较结果 | ||||
|  */ | ||||
| @Data | ||||
| public class ActivityConcComparResult implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * 观测值 | ||||
|      */ | ||||
|     private double[] obsValues; | ||||
|     /** | ||||
|      * 模拟值 | ||||
|      */ | ||||
|     private double[] modValues; | ||||
|     /** | ||||
|      * mdc值 | ||||
|      */ | ||||
|     private double[] mdcValues; | ||||
|     /** | ||||
|      * 台站列表 | ||||
|      */ | ||||
|     private String[] stations; | ||||
| } | ||||
|  | @ -0,0 +1,23 @@ | |||
| package org.jeecg.vo; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| 
 | ||||
| /** | ||||
|  * lon、lat、log10_Q、tstart、tstop直方图数据 | ||||
|  */ | ||||
| @Data | ||||
| public class HistogramChartBarData { | ||||
| 
 | ||||
|     /** | ||||
|      * 每个柱子的左边界值 | ||||
|      */ | ||||
|     private Object xLeftVal; | ||||
|     /** | ||||
|      * 每个柱子的右边界值 | ||||
|      */ | ||||
|     private Object xRightVal; | ||||
|     /** | ||||
|      * 每个柱子的Y轴值 | ||||
|      */ | ||||
|     private Long yValue; | ||||
| } | ||||
|  | @ -0,0 +1,37 @@ | |||
| package org.jeecg.vo; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * lon、lat、log10_Q、tstart、tstop直方图数据结构 | ||||
|  */ | ||||
| @Data | ||||
| public class HistogramChartStru implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * X轴最小值 | ||||
|      */ | ||||
|     private Object xMin; | ||||
| 
 | ||||
|     /** | ||||
|      * X轴最大值 | ||||
|      */ | ||||
|     private Object xMax; | ||||
| 
 | ||||
|     /** | ||||
|      * 中位数 | ||||
|      */ | ||||
|     private Object postMedian; | ||||
| 
 | ||||
|     /** | ||||
|      * 柱状图bar数据 | ||||
|      */ | ||||
|     private List<HistogramChartBarData> histogramChartBarDataList; | ||||
| 
 | ||||
|     /** | ||||
|      * 先验分布List | ||||
|      */ | ||||
|     private List<PriorDistribution> priorDistributionList; | ||||
| } | ||||
|  | @ -0,0 +1,16 @@ | |||
| package org.jeecg.vo; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| /** | ||||
|  * 直方图先验分布数据 | ||||
|  */ | ||||
| @Data | ||||
| public class PriorDistribution implements Serializable { | ||||
| 
 | ||||
|     private Object xValue; | ||||
| 
 | ||||
|     private Object yValue; | ||||
| } | ||||
|  | @ -0,0 +1,41 @@ | |||
| package org.jeecg.vo; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| /** | ||||
|  * 概率分布图数据 | ||||
|  */ | ||||
| @Data | ||||
| public class SourceProbabilityGrid implements Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * 概率分布数据 | ||||
|      */ | ||||
|     private double[][] data; | ||||
|     /** | ||||
|      * 最小经度 | ||||
|      */ | ||||
|     private double lonmin; | ||||
|     /** | ||||
|      * 最小纬度 | ||||
|      */ | ||||
|     private double latmin; | ||||
|     /** | ||||
|      * 最大经度 | ||||
|      */ | ||||
|     private double lonmax; | ||||
|     /** | ||||
|      * 最大纬度 | ||||
|      */ | ||||
|     private double latmax; | ||||
|     /** | ||||
|      * 行数 | ||||
|      */ | ||||
|     private int rows; | ||||
|     /** | ||||
|      * 列数 | ||||
|      */ | ||||
|     private int cols; | ||||
| } | ||||
							
								
								
									
										91
									
								
								jeecg-module-source-rebuild/src/test/java/RTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								jeecg-module-source-rebuild/src/test/java/RTest.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,91 @@ | |||
| import org.rosuda.REngine.*; | ||||
| import org.rosuda.REngine.Rserve.RConnection; | ||||
| import org.rosuda.REngine.Rserve.RserveException; | ||||
| 
 | ||||
| public class RTest { | ||||
| 
 | ||||
|     public static void main(String[] args) throws RserveException, REXPMismatchException { | ||||
|         String host = "192.168.186.142"; | ||||
|         int port = 6311; | ||||
|         // 如果有认证 | ||||
|         String user = "rserve"; | ||||
|         String password = "123456"; | ||||
|         String scriptPath = "/home/centos/r_workspace/FREAR-master/test_case/expdir/main.R"; | ||||
| 
 | ||||
|         RConnection conn = new RConnection(host, port); | ||||
|         conn.login(user, password); | ||||
|         System.out.println(conn.isConnected()); | ||||
|         if(conn.isConnected()){ | ||||
|             //重建任务名称 | ||||
|             conn.assign("experiment", "test"); | ||||
|             //重建任务输入数据目录 | ||||
|             conn.assign("expdir", "test_case/expdir"); | ||||
|             conn.assign("datadir", "test_case/data"); | ||||
|             //重建任务输出数据目录 | ||||
|             conn.assign("outbasedir", "/home/centos/r_workspace/work_output"); | ||||
|             //数据库相关 | ||||
|             conn.assign("dbHost", "192.168.42.54"); | ||||
|             conn.assign("dbPort", new REXPInteger(5432)); | ||||
|             conn.assign("dbName", "stas"); | ||||
|             conn.assign("dbUser", "stas"); | ||||
|             conn.assign("dbPassword", "123456"); | ||||
|             //任务关联ID | ||||
|             conn.assign("taskId", "8"); | ||||
|             //半衰期 | ||||
|            conn.assign("halflife", new REXPDouble(5.243)); | ||||
|             //设置最小总累积源项Bq | ||||
|            conn.assign("Qmin", new REXPDouble(Math.pow(10, 5))); | ||||
|             //设置最大总累积源项Bq | ||||
|            conn.assign("Qmax", new REXPDouble(Math.pow(10, 15))); | ||||
| 
 | ||||
|             //未知源#settings$trueValues <- c(NA,NA,NA,NA,NA) | ||||
|             //已知源位置经度 | ||||
|             //已知源位置纬度 | ||||
|             //已知源位置源强 | ||||
|             //已知源位置开始时间 | ||||
|             //已知源结束时间 | ||||
| 
 | ||||
|             // 反演经纬度、分辨率 | ||||
|             conn.eval("domain <- list(lonmin=125, latmin=38, lonmax=130, latmax=40, dx=.5, dy=.5)"); | ||||
|             //设置工作目录 | ||||
|             conn.eval("setwd(\"/home/centos/r_workspace/FREAR-master\")"); | ||||
|             //执行脚本 | ||||
|             conn.eval("source(\"test_case/expdir/set_up.R\")"); | ||||
|             REXP outputREXP = conn.eval("capture.output({source(\"test_case/expdir/main.R\")})"); | ||||
|             // 将输出作为字符串数组获取 | ||||
|             String[] outputLines = outputREXP.asStrings(); | ||||
| 
 | ||||
|             for (String line : outputLines) { | ||||
|                 System.out.println("[R LOG] " + line); // 在Java控制台打印日志 | ||||
|                 // 你也可以将日志存入变量、文件或发送到日志系统 | ||||
|             } | ||||
|             //读取数据 | ||||
| //            String rdsPath = "/home/centos/r_workspace/work_output/测试任务1/FREAR_syntheticTestCase_subexp1_20250909_1128/probloc.RDS"; | ||||
| //            REXP result = conn.eval("readRDS('" + rdsPath + "')"); | ||||
| // | ||||
| //            if (result.isNumeric()) { | ||||
| //                double[][] values = result.asDoubleMatrix(); | ||||
| //                System.out.println("Numeric vector, length: " + values.length); | ||||
| //                for (int i = 0; i < values.length; i++) { | ||||
| //                    for (int j = 0; j < values[i].length; j++) { | ||||
| //                        System.out.print(values[i][j] + " "); | ||||
| //                    } | ||||
| //                    System.out.println(); // 换行 | ||||
| //                } | ||||
| //            } | ||||
| //            else if (result.isString()) { | ||||
| //                String[] strings = result.asStrings(); | ||||
| //                System.out.println("String vector:"); | ||||
| //                for (String s : strings) System.out.println(s); | ||||
| //            } | ||||
| //            else if (result.isList()) { | ||||
| //                // 如果是列表(list),可以进一步解析 | ||||
| //                System.out.println("It's a list with " + result.length() + " elements"); | ||||
| //                // 可递归处理 | ||||
| //            } | ||||
|         } | ||||
|         conn.close(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										6
									
								
								jeecg-module-source-rebuild/src/test/java/RTest1.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								jeecg-module-source-rebuild/src/test/java/RTest1.java
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| public class RTest1 { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println(Math.pow(10, 15)); | ||||
|     } | ||||
| } | ||||
|  | @ -5,7 +5,6 @@ import com.baomidou.mybatisplus.extension.service.IService; | |||
| import org.jeecg.common.system.query.PageRequest; | ||||
| import org.jeecg.modules.base.entity.WeatherTask; | ||||
| import org.jeecg.modules.base.entity.WeatherTaskLog; | ||||
| 
 | ||||
| import java.time.LocalDate; | ||||
| import java.util.List; | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage; | |||
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import lombok.val; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.jeecg.common.constant.enums.WeatherTaskStatusEnum; | ||||
| import org.jeecg.common.system.query.PageRequest; | ||||
|  | @ -18,6 +17,7 @@ import org.springframework.stereotype.Service; | |||
| import org.springframework.transaction.annotation.Transactional; | ||||
| 
 | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
| 
 | ||||
|  | @ -43,7 +43,11 @@ public class WeatherTaskServiceImpl extends ServiceImpl<WeatherTaskMapper, Weath | |||
|     public IPage<WeatherTask> page(PageRequest pageRequest, String taskName, Integer taskStatus, LocalDate startDate,LocalDate endDate) { | ||||
|         LambdaQueryWrapper<WeatherTask> queryWrapper = new LambdaQueryWrapper<>(); | ||||
|         queryWrapper.eq(Objects.nonNull(taskStatus),WeatherTask::getTaskStatus, taskStatus); | ||||
|         queryWrapper.between((Objects.nonNull(startDate) && Objects.nonNull(endDate)),WeatherTask::getStartDate,startDate,endDate); | ||||
|         if(Objects.nonNull(startDate) && Objects.nonNull(endDate)){ | ||||
|             LocalDateTime startDateTime = startDate.atTime(0, 0, 0); | ||||
|             LocalDateTime endDateTime = endDate.atTime(23, 59, 59); | ||||
|             queryWrapper.between(WeatherTask::getStartDate,startDateTime,endDateTime); | ||||
|         } | ||||
|         queryWrapper.like(StringUtils.isNotBlank(taskName),WeatherTask::getTaskName,taskName); | ||||
|         queryWrapper.orderByDesc(WeatherTask::getStartDate); | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
|         <version>3.8.1</version> | ||||
|     </parent> | ||||
| 
 | ||||
|     <artifactId>jeecg-sourceitem-reconstruction-start</artifactId> | ||||
|     <artifactId>jeecg-source-rebuild-start</artifactId> | ||||
| 
 | ||||
|     <properties> | ||||
|         <maven.compiler.source>17</maven.compiler.source> | ||||
|  | @ -29,7 +29,7 @@ | |||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.jeecgframework.boot</groupId> | ||||
|             <artifactId>jeecg-module-sourceitem-reconstruction</artifactId> | ||||
|             <artifactId>jeecg-module-source-rebuild</artifactId> | ||||
|             <version>${jeecgboot.version}</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|  | @ -22,17 +22,17 @@ import java.net.UnknownHostException; | |||
| @SpringBootApplication | ||||
| @RequiredArgsConstructor | ||||
| @EnableFeignClients | ||||
| public class JeecgSourceItemReconstructionCloudApplication extends SpringBootServletInitializer implements CommandLineRunner { | ||||
| public class JeecgSourceRebuildCloudApplication extends SpringBootServletInitializer implements CommandLineRunner { | ||||
| 
 | ||||
|     private final RedisTemplate<String, Object> redisTemplate; | ||||
| 
 | ||||
|     @Override | ||||
|     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { | ||||
|         return application.sources(JeecgSourceItemReconstructionCloudApplication.class); | ||||
|         return application.sources(JeecgSourceRebuildCloudApplication.class); | ||||
|     } | ||||
| 
 | ||||
|     public static void main(String[] args) throws UnknownHostException { | ||||
|         ConfigurableApplicationContext application = SpringApplication.run(JeecgSourceItemReconstructionCloudApplication.class, args); | ||||
|         ConfigurableApplicationContext application = SpringApplication.run(JeecgSourceRebuildCloudApplication.class, args); | ||||
|         Environment env = application.getEnvironment(); | ||||
|         String ip = InetAddress.getLocalHost().getHostAddress(); | ||||
|         String port = env.getProperty("server.port"); | ||||
|  | @ -0,0 +1,24 @@ | |||
| server: | ||||
|   port: 8002 | ||||
| 
 | ||||
| spring: | ||||
|   application: | ||||
|     name: jeecg-source-rebuild | ||||
|   cloud: | ||||
|     nacos: | ||||
|       config: | ||||
|         server-addr: @config.server-addr@ | ||||
|         group: @config.group@ | ||||
|         namespace: @config.namespace@ | ||||
|         username: @config.username@ | ||||
|         password: @config.password@ | ||||
|       discovery: | ||||
|         server-addr: ${spring.cloud.nacos.config.server-addr} | ||||
|         group: @config.group@ | ||||
|         namespace: @config.namespace@ | ||||
|         username: @config.username@ | ||||
|         password: @config.password@ | ||||
|   config: | ||||
|     import: | ||||
|       - optional:nacos:jeecg.yaml | ||||
|       - optional:nacos:jeecg-@profile.name@.yaml | ||||
|  | @ -0,0 +1,77 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <configuration debug="false"> | ||||
| 	<!--定义日志文件的存储地址 --> | ||||
| 	<property name="LOG_HOME" value="../logs" /> | ||||
| 
 | ||||
| 	<!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />--> | ||||
| 	<!-- 控制台输出 --> | ||||
| 	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||||
| 		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> | ||||
| 			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 | ||||
| 			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>--> | ||||
| 			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n</pattern> | ||||
| 		</encoder> | ||||
| 	</appender> | ||||
| 
 | ||||
| 	<!-- 按照每天生成日志文件 --> | ||||
| 	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||||
| 		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | ||||
| 			<!--日志文件输出的文件名 --> | ||||
| 			<FileNamePattern>${LOG_HOME}/jeecg-system-%d{yyyy-MM-dd}.%i.log</FileNamePattern> | ||||
| 			<!--日志文件保留天数 --> | ||||
| 			<MaxHistory>30</MaxHistory> | ||||
| 			<maxFileSize>10MB</maxFileSize> | ||||
| 		</rollingPolicy> | ||||
| 		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> | ||||
| 			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 --> | ||||
| 			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern> | ||||
| 		</encoder> | ||||
| 	</appender> | ||||
| 
 | ||||
| 	<!-- 生成 error html格式日志开始 --> | ||||
| 	<appender name="HTML" class="ch.qos.logback.core.FileAppender"> | ||||
| 		<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> | ||||
| 			<!--设置日志级别,过滤掉info日志,只输入error日志--> | ||||
| 			<level>ERROR</level> | ||||
| 		</filter> | ||||
| 		<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> | ||||
| 			<layout class="ch.qos.logback.classic.html.HTMLLayout"> | ||||
| 				<pattern>%p%d%msg%M%F{32}%L</pattern> | ||||
| 			</layout> | ||||
| 		</encoder> | ||||
| 		<file>${LOG_HOME}/error-log.html</file> | ||||
| 	</appender> | ||||
| 	<!-- 生成 error html格式日志结束 --> | ||||
| 
 | ||||
| 	<!-- 每天生成一个html格式的日志开始 --> | ||||
| 	<appender name="FILE_HTML" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||||
| 		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | ||||
| 			<!--日志文件输出的文件名 --> | ||||
| 			<FileNamePattern>${LOG_HOME}/jeecg-system-%d{yyyy-MM-dd}.%i.html</FileNamePattern> | ||||
| 			<!--日志文件保留天数 --> | ||||
| 			<MaxHistory>30</MaxHistory> | ||||
| 			<MaxFileSize>10MB</MaxFileSize> | ||||
| 		</rollingPolicy> | ||||
| 		<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> | ||||
| 			<layout class="ch.qos.logback.classic.html.HTMLLayout"> | ||||
| 				<pattern>%p%d%msg%M%F{32}%L</pattern> | ||||
| 			</layout> | ||||
| 		</encoder> | ||||
| 	</appender> | ||||
| 	<!-- 每天生成一个html格式的日志结束 --> | ||||
| 
 | ||||
| 	<!--myibatis log configure --> | ||||
| 	<logger name="com.apache.ibatis" level="TRACE" /> | ||||
| 	<logger name="java.sql.Connection" level="DEBUG" /> | ||||
| 	<logger name="java.sql.Statement" level="DEBUG" /> | ||||
| 	<logger name="java.sql.PreparedStatement" level="DEBUG" /> | ||||
| 
 | ||||
| 	<!-- 日志输出级别 --> | ||||
| 	<root level="INFO"> | ||||
| 		<appender-ref ref="STDOUT" /> | ||||
| 		<appender-ref ref="FILE" /> | ||||
| 		<appender-ref ref="HTML" /> | ||||
| 		<appender-ref ref="FILE_HTML" /> | ||||
| 	</root> | ||||
| 
 | ||||
| </configuration> | ||||
|  | @ -22,7 +22,7 @@ | |||
|         <module>jeecg-visual</module> | ||||
|         <module>jeecg-weather-start</module> | ||||
|         <module>jeecg-data-analyze-start</module> | ||||
|         <module>jeecg-sourceitem-reconstruction-start</module> | ||||
|         <module>jeecg-source-rebuild-start</module> | ||||
|     </modules> | ||||
| 
 | ||||
| </project> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 panbaolin
						panbaolin