diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/SourceRebuildReleaseSourceEnum.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/SourceRebuildReleaseSourceEnum.java new file mode 100644 index 0000000..b455ad4 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/SourceRebuildReleaseSourceEnum.java @@ -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; + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/SourceRebuildTaskStatusEnum.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/SourceRebuildTaskStatusEnum.java new file mode 100644 index 0000000..f12d8ce --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/SourceRebuildTaskStatusEnum.java @@ -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; + } +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/properties/SourceRebuildParams.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/properties/SourceRebuildParams.java new file mode 100644 index 0000000..5458f73 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/properties/SourceRebuildParams.java @@ -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; + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/properties/SystemStorageProperties.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/properties/SystemStorageProperties.java index ab9448d..bc32a9f 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/properties/SystemStorageProperties.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/properties/SystemStorageProperties.java @@ -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; } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildMonitoringData.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildMonitoringData.java new file mode 100644 index 0000000..fe1a7b8 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildMonitoringData.java @@ -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; +} \ No newline at end of file diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildTask.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildTask.java new file mode 100644 index 0000000..f0c99d6 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildTask.java @@ -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; +} \ No newline at end of file diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildTaskLog.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildTaskLog.java new file mode 100644 index 0000000..a3bdc89 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/SourceRebuildTaskLog.java @@ -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; + } +} \ No newline at end of file diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/WeatherData.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/WeatherData.java index 1c0020c..86edf51 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/WeatherData.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/WeatherData.java @@ -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 diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/WeatherTaskLog.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/WeatherTaskLog.java index 8f38d86..9931279 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/WeatherTaskLog.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/WeatherTaskLog.java @@ -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 diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildMonitoringDataMapper.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildMonitoringDataMapper.java new file mode 100644 index 0000000..a576d81 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildMonitoringDataMapper.java @@ -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 { +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildTaskLogMapper.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildTaskLogMapper.java new file mode 100644 index 0000000..10319e8 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildTaskLogMapper.java @@ -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 { + +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildTaskMapper.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildTaskMapper.java new file mode 100644 index 0000000..8ff41a8 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/SourceRebuildTaskMapper.java @@ -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 { +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildMonitoringDataMapper.xml b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildMonitoringDataMapper.xml new file mode 100644 index 0000000..291f2cd --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildMonitoringDataMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildTaskLogMapper.xml b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildTaskLogMapper.xml new file mode 100644 index 0000000..8ccd371 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildTaskLogMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildTaskMapper.xml b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildTaskMapper.xml new file mode 100644 index 0000000..8727671 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/mapper/xml/SourceRebuildTaskMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-module-sourceitem-reconstruction/pom.xml b/jeecg-module-source-rebuild/pom.xml similarity index 64% rename from jeecg-module-sourceitem-reconstruction/pom.xml rename to jeecg-module-source-rebuild/pom.xml index ca7b9b9..dbde7b8 100644 --- a/jeecg-module-sourceitem-reconstruction/pom.xml +++ b/jeecg-module-source-rebuild/pom.xml @@ -9,12 +9,14 @@ 3.8.1 - jeecg-module-sourceitem-reconstruction + jeecg-module-source-rebuild 17 17 UTF-8 + 2.1.0 + 1.8.1 @@ -23,5 +25,15 @@ jeecg-boot-base-core ${jeecgboot.version} + + org.rosuda.REngine + REngine + ${rEngine.version} + + + org.rosuda.REngine + Rserve + ${rserve.version} + \ No newline at end of file diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/SourceRebuildTaskController.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/SourceRebuildTaskController.java new file mode 100644 index 0000000..aac99e9 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/SourceRebuildTaskController.java @@ -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 page = sourceRebuildTaskService.page(pageRequest, taskName, taskStatus, startDate,endDate); + Map 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(); + } +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/TaskMonitoringDataController.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/TaskMonitoringDataController.java new file mode 100644 index 0000000..72047bd --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/TaskMonitoringDataController.java @@ -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 fileMap = multipartRequest.getFileMap(); + for (Map.Entry 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 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("文件导入失败!"); + } +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/TaskResultDataController.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/TaskResultDataController.java new file mode 100644 index 0000000..dfea540 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/controller/TaskResultDataController.java @@ -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 { + + } +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildMonitoringDataService.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildMonitoringDataService.java new file mode 100644 index 0000000..a2d574c --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildMonitoringDataService.java @@ -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 { + + /** + * 保存源项重建任务监测数据 + * @param monitoringDatas + */ + void cteate(List monitoringDatas); + + /** + * 删除源项重建任务监测数据 + * @param taskId + */ + void delete(Integer taskId); + + /** + * 获取任务所属监测数据 + * @param taskId + * @return + */ + List getTaskMonitoringData(Integer taskId); + +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildTaskLogService.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildTaskLogService.java new file mode 100644 index 0000000..ce10863 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildTaskLogService.java @@ -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 { + + /** + * 保存源项重建任务运行过程日志 + * @param sourceRebuildTaskLog + */ + void cteate(SourceRebuildTaskLog sourceRebuildTaskLog); + + /** + * 删除任务运行过程日志 + * @param taskId + */ + void delete(Integer taskId); + + /** + * 获取任务运行过程日志 + * @param taskId + * @return + */ + List getTaskLogs(Integer taskId); + + /** + * 批量保存日志 + * @param logs + */ + void batchCteate(List logs); +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildTaskService.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildTaskService.java new file mode 100644 index 0000000..a75eca4 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/SourceRebuildTaskService.java @@ -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 { + + /** + * 分页查询任务列表 + * @param pageRequest + * @param taskName + * @param taskStatus + * @param startDate + * @param endDate + * @return + */ + IPage 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 getTaskLog(Integer taskId); + + /** + * 修改任务状态 + * @param taskId + * @param taskStatus + */ + void updateTaskStatus(Integer taskId, Integer taskStatus); + + /** + * 任务耗时 + * @param taskId + * @param taskTimeConsuming + */ + void updateTaskTimeConsuming(Integer taskId, Integer taskTimeConsuming); +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/TaskResultDataService.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/TaskResultDataService.java new file mode 100644 index 0000000..63458a0 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/TaskResultDataService.java @@ -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 getBayesMonovarPosterior(Integer taskId); +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildMonitoringDataServiceImpl.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildMonitoringDataServiceImpl.java new file mode 100644 index 0000000..b65f509 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildMonitoringDataServiceImpl.java @@ -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 implements SourceRebuildMonitoringDataService { + + /** + * 保存源项重建任务监测数据 + * + * @param monitoringDatas + */ + @Transactional(rollbackFor = RuntimeException.class) + @Override + public void cteate(List monitoringDatas) { + this.saveBatch(monitoringDatas); + } + + /** + * 删除源项重建任务监测数据 + * + * @param taskId + */ + @Transactional(rollbackFor = RuntimeException.class) + @Override + public void delete(Integer taskId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SourceRebuildMonitoringData::getTaskId, taskId); + this.remove(queryWrapper); + } + + /** + * 获取任务所属监测数据 + * + * @param taskId + * @return + */ + @Override + public List getTaskMonitoringData(Integer taskId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SourceRebuildMonitoringData::getTaskId, taskId); + queryWrapper.ne(SourceRebuildMonitoringData::getStation,"USX77"); + queryWrapper.orderByAsc(SourceRebuildMonitoringData::getCollectStop); + return this.baseMapper.selectList(queryWrapper); + } +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildTaskLogServiceImpl.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildTaskLogServiceImpl.java new file mode 100644 index 0000000..61a6e6c --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildTaskLogServiceImpl.java @@ -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 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 queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SourceRebuildTaskLog::getTaskId, taskId); + this.baseMapper.delete(queryWrapper); + } + + /** + * 获取任务运行过程日志 + * + * @param taskId + * @return + */ + @Override + public List getTaskLogs(Integer taskId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SourceRebuildTaskLog::getTaskId, taskId); + return this.baseMapper.selectList(queryWrapper); + } + + /** + * 批量保存日志 + * + * @param logs + */ + @Transactional(rollbackFor = RuntimeException.class) + @Override + public void batchCteate(List logs) { + this.saveBatch(logs); + } +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildTaskServiceImpl.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildTaskServiceImpl.java new file mode 100644 index 0000000..c292a70 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/SourceRebuildTaskServiceImpl.java @@ -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 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 page(PageRequest pageRequest, String taskName, Integer taskStatus, LocalDate startDate, LocalDate endDate) { + LambdaQueryWrapper 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 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 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 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 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 getTaskLog(Integer taskId) { + LambdaQueryWrapper 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); + } +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/TaskResultDataServiceImpl.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/TaskResultDataServiceImpl.java new file mode 100644 index 0000000..723423a --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/service/impl/TaskResultDataServiceImpl.java @@ -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 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 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 lonChartDataMap = this.processLonChart(chaindf, post_median, breaks, zprior); + Map latChartDataMap = this.processLatChart(chaindf, post_median, breaks, zprior); + Map log10ChartDataMap = this.processLog10Chart(chaindf, post_median, breaks, zprior); + Map startChartDataMap = this.processStartChart(chaindf, post_median, breaks, zprior); + Map 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 processLonChart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { + Map 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 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 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 processLatChart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { + Map 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 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 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 processLog10Chart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { + Map 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 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 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 processStartChart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { + Map 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 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 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 processStopChart(REXP chaindf,REXP postMedian,REXP breaks,REXP zprior) throws REXPMismatchException { + Map 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 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 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); + } +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/task/SourceRebuildTaskExec.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/task/SourceRebuildTaskExec.java new file mode 100644 index 0000000..e9e2fca --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/task/SourceRebuildTaskExec.java @@ -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 taskMonitoringDatas; + private SourceRebuildTaskLogService sourceRebuildTaskLogService; + private SourceRebuildTask sourceRebuildTask; + private SourceRebuildParams sourceRebuildParams; + private SourceRebuildTaskService sourceRebuildTaskService; + + /** + * 初始化 + */ + public void init(SystemStorageProperties systemStorageProperties, + List 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 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 allSRSFileMap = new HashMap<>(); + Map finalSRSFileMap = new TreeMap<>(); + //根据监测数据校验SRS文件,如果缺少SRS文件也报错 + String srsFilePath = this.getSRSFilePath(); + Path dirpath = Paths.get(srsFilePath); + try(Stream 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 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 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 logs = new ArrayList<>(); + for(String logContent : logContents){ + logs.add(new SourceRebuildTaskLog(sourceRebuildTask.getId(),logContent)); + } + sourceRebuildTaskLogService.batchCteate(logs); + } +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/ActivityConcComparResult.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/ActivityConcComparResult.java new file mode 100644 index 0000000..4059e95 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/ActivityConcComparResult.java @@ -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; +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/HistogramChartBarData.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/HistogramChartBarData.java new file mode 100644 index 0000000..1a5ec48 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/HistogramChartBarData.java @@ -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; +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/HistogramChartStru.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/HistogramChartStru.java new file mode 100644 index 0000000..aff966d --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/HistogramChartStru.java @@ -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 histogramChartBarDataList; + + /** + * 先验分布List + */ + private List priorDistributionList; +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/PriorDistribution.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/PriorDistribution.java new file mode 100644 index 0000000..1ed9143 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/PriorDistribution.java @@ -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; +} diff --git a/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/SourceProbabilityGrid.java b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/SourceProbabilityGrid.java new file mode 100644 index 0000000..236c2f9 --- /dev/null +++ b/jeecg-module-source-rebuild/src/main/java/org/jeecg/vo/SourceProbabilityGrid.java @@ -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; +} diff --git a/jeecg-module-source-rebuild/src/test/java/RTest.java b/jeecg-module-source-rebuild/src/test/java/RTest.java new file mode 100644 index 0000000..b8c8858 --- /dev/null +++ b/jeecg-module-source-rebuild/src/test/java/RTest.java @@ -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(); + } + + +} diff --git a/jeecg-module-source-rebuild/src/test/java/RTest1.java b/jeecg-module-source-rebuild/src/test/java/RTest1.java new file mode 100644 index 0000000..66c7987 --- /dev/null +++ b/jeecg-module-source-rebuild/src/test/java/RTest1.java @@ -0,0 +1,6 @@ +public class RTest1 { + + public static void main(String[] args) { + System.out.println(Math.pow(10, 15)); + } +} diff --git a/jeecg-module-weather/src/main/java/org/jeecg/service/WeatherTaskService.java b/jeecg-module-weather/src/main/java/org/jeecg/service/WeatherTaskService.java index cf7aa72..e362145 100644 --- a/jeecg-module-weather/src/main/java/org/jeecg/service/WeatherTaskService.java +++ b/jeecg-module-weather/src/main/java/org/jeecg/service/WeatherTaskService.java @@ -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; diff --git a/jeecg-module-weather/src/main/java/org/jeecg/service/impl/WeatherTaskServiceImpl.java b/jeecg-module-weather/src/main/java/org/jeecg/service/impl/WeatherTaskServiceImpl.java index f33ed47..29abbc5 100644 --- a/jeecg-module-weather/src/main/java/org/jeecg/service/impl/WeatherTaskServiceImpl.java +++ b/jeecg-module-weather/src/main/java/org/jeecg/service/impl/WeatherTaskServiceImpl.java @@ -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 page(PageRequest pageRequest, String taskName, Integer taskStatus, LocalDate startDate,LocalDate endDate) { LambdaQueryWrapper 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); diff --git a/jeecg-server-cloud/jeecg-sourceitem-reconstruction-start/pom.xml b/jeecg-server-cloud/jeecg-source-rebuild-start/pom.xml similarity index 89% rename from jeecg-server-cloud/jeecg-sourceitem-reconstruction-start/pom.xml rename to jeecg-server-cloud/jeecg-source-rebuild-start/pom.xml index 88fa1f2..993f0da 100644 --- a/jeecg-server-cloud/jeecg-sourceitem-reconstruction-start/pom.xml +++ b/jeecg-server-cloud/jeecg-source-rebuild-start/pom.xml @@ -9,7 +9,7 @@ 3.8.1 - jeecg-sourceitem-reconstruction-start + jeecg-source-rebuild-start 17 @@ -29,7 +29,7 @@ org.jeecgframework.boot - jeecg-module-sourceitem-reconstruction + jeecg-module-source-rebuild ${jeecgboot.version} diff --git a/jeecg-server-cloud/jeecg-sourceitem-reconstruction-start/src/main/java/org/jeecg/JeecgSourceItemReconstructionCloudApplication.java b/jeecg-server-cloud/jeecg-source-rebuild-start/src/main/java/org/jeecg/JeecgSourceRebuildCloudApplication.java similarity index 88% rename from jeecg-server-cloud/jeecg-sourceitem-reconstruction-start/src/main/java/org/jeecg/JeecgSourceItemReconstructionCloudApplication.java rename to jeecg-server-cloud/jeecg-source-rebuild-start/src/main/java/org/jeecg/JeecgSourceRebuildCloudApplication.java index e583ba0..b6dd19a 100644 --- a/jeecg-server-cloud/jeecg-sourceitem-reconstruction-start/src/main/java/org/jeecg/JeecgSourceItemReconstructionCloudApplication.java +++ b/jeecg-server-cloud/jeecg-source-rebuild-start/src/main/java/org/jeecg/JeecgSourceRebuildCloudApplication.java @@ -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 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"); diff --git a/jeecg-server-cloud/jeecg-source-rebuild-start/src/main/resources/application.yml b/jeecg-server-cloud/jeecg-source-rebuild-start/src/main/resources/application.yml new file mode 100644 index 0000000..475c0a1 --- /dev/null +++ b/jeecg-server-cloud/jeecg-source-rebuild-start/src/main/resources/application.yml @@ -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 \ No newline at end of file diff --git a/jeecg-server-cloud/jeecg-source-rebuild-start/src/main/resources/logback-spring.xml b/jeecg-server-cloud/jeecg-source-rebuild-start/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..60d4c7d --- /dev/null +++ b/jeecg-server-cloud/jeecg-source-rebuild-start/src/main/resources/logback-spring.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n + + + + + + + + ${LOG_HOME}/jeecg-system-%d{yyyy-MM-dd}.%i.log + + 30 + 10MB + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n + + + + + + + + ERROR + + + + %p%d%msg%M%F{32}%L + + + ${LOG_HOME}/error-log.html + + + + + + + + ${LOG_HOME}/jeecg-system-%d{yyyy-MM-dd}.%i.html + + 30 + 10MB + + + + %p%d%msg%M%F{32}%L + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jeecg-server-cloud/pom.xml b/jeecg-server-cloud/pom.xml index 7c306b3..e20ad19 100644 --- a/jeecg-server-cloud/pom.xml +++ b/jeecg-server-cloud/pom.xml @@ -22,7 +22,7 @@ jeecg-visual jeecg-weather-start jeecg-data-analyze-start - jeecg-sourceitem-reconstruction-start + jeecg-source-rebuild-start \ No newline at end of file diff --git a/pom.xml b/pom.xml index bbf4831..cae3a51 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ jeecg-module-system jeecg-module-weather jeecg-module-data-analyze - jeecg-module-sourceitem-reconstruction + jeecg-module-source-rebuild