diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/original/GardsSampleData.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/original/GardsSampleData.java new file mode 100644 index 0000000..9d2c872 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/original/GardsSampleData.java @@ -0,0 +1,198 @@ +package org.jeecg.modules.base.entity.original; + + +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 org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("ORIGINAL.GARDS_SAMPLE_DATA") +public class GardsSampleData implements Serializable { + + /** + * 探测器编码 + */ + @Excel(name = "DETECTOR CODE",orderNum = "3",width = 20) + @TableField(value = "SITE_DET_CODE") + private String siteDetCode; + + /** + * 样品id + */ + + @TableId(type = IdType.AUTO) + private Integer sampleId; + + /** + * 台站id + */ + @TableField(value = "STATION_ID") + private Integer stationId; + + /** + * 探测器id + */ + + @TableField(value = "DETECTOR_ID") + private Integer detectorId; + + /** + * 导入文件名称 + */ + + @TableField(value = "INPUT_FILE_NAME") + private String inputFileName; + + /** + * 系统类型(P : particulate; B :gas with 3-D β-γ coincidence detection; G :all other gas systems (high-resolution + * γ-spectrometry or 2-D β-γ coincidence + * detection)) + */ + + @TableField(value = "SAMPLE_TYPE") + private String sampleType; + + /** + * 数据类型(S:SAMPLEPHD + * B:BLANKPHD + * D:DETBKPHD + * G:GASBKPHD + * C:CALIBPHD + * Q:QCPHD) + */ + + @TableField(value = "DATA_TYPE") + private String dataType; + + /** + * 几何尺寸 + */ + @TableField(value = "GEOMETRY") + private String geometry; + + /** + * 能谱限定符: 过程谱(PREL) 和 全谱(FULL) + */ + @Excel(name = "SPECTRAL QUALIFIER",orderNum = "4",width = 30) + @TableField(value = "SPECTRAL_QUALIFIE") + private String spectralQualifie; + + /** + * 报文发送日期 + */ + @TableField(value = "TRANSMIT_DTG") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date transmitDtg; + + /** + * 样品采集开始时间 + */ + @TableField(value = "COLLECT_START") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "COLLECTION START TIME",format = "yyyy-MM-dd HH:mm:ss",orderNum = "5",width = 30) + private Date collectStart; + + /** + * 样品采集结束时间 + */ + @TableField(value = "COLLECT_STOP") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "COLLECTION STOP TIME",format = "yyyy-MM-dd HH:mm:ss",orderNum = "6",width = 30) + private Date collectStop; + + /** + * 样品测量开始时间 + */ + @TableField(value = "ACQUISITION_START") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "ACQUISITION START TIME",format = "yyyy-MM-dd HH:mm:ss",orderNum = "5",width = 30) + private Date acquisitionStart; + + /** + * 样品测量结束时间 + */ + @TableField(value = "ACQUISITION_STOP") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "ACQUISITION STOP TIME",format = "yyyy-MM-dd HH:mm:ss",orderNum = "6",width = 30) + private Date acquisitionStop; + + /** + * 能谱获取实时间 + */ + + @TableField(value = "ACQUISITION_REAL_SEC") + private Double acquisitionRealSec; + + /** + * 能谱获取活时间 + */ + + @TableField(value = "ACQUISITION_LIVE_SEC") + private Double acquisitionLiveSec; + + /** + * 采样量(立方米) + */ + + @TableField(value = "QUANTITY") + private Double quantity; + + /** + * 样品处理状态 + */ + + @TableField(value = "STATUS") + private String status; + + /** + * 样品级别 + */ + + @TableField(value = "RNAUTO_GRADING") + private Integer rnautoGarding; + + /** + * 样品级别 + */ + + @TableField(value = "RNMAN_GRADING") + private Integer rnmanGarding; + + /** + * 样品阈值 + */ + + @TableField(value = "RNAUTO_THRESHOLD") + private String rnautoThreshold; + + /** + * 样品阈值 + */ + + @TableField(value = "RNMAN_THRESHOLD") + private String rnmanThreshold; + + + /** + * 操作时间 + */ + @TableField(value = "MODDATE") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date moddate; + + +} \ No newline at end of file diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnauto/GardsNuclIded.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnauto/GardsNuclIded.java new file mode 100644 index 0000000..6daa7ec --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnauto/GardsNuclIded.java @@ -0,0 +1,119 @@ +package org.jeecg.modules.base.entity.rnauto; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * 存储gamma谱中识别到的核素计算结果。 + */ +@Data +@TableName("RNAUTO.GARDS_NUCL_IDED") +public class GardsNuclIded implements Serializable { + + /** + * 样品id + */ + @TableField(value = "SAMPLE_ID") + private Integer sampleId; + /** + * 分析ID号 + */ + @TableField(value = "IDANALYSIS") + private Integer idAnalysis; + /** + * 核素名称 + */ + @TableField(value = "NUCLIDENAME") + private String nuclideName; + /** + * 核素类型 + */ + @TableField(value = "TYPE") + private String type; + /** + * 核素半衰期 + */ + @TableField(value = "HALFLIFE") + private String halflife; + /** + * 平均活度值 + */ + @TableField(value = "AVE_ACTIV") + private String aveActiv; + /** + * 平均活度值不确定度 + */ + @TableField(value = "AVE_ACTIV_ERR") + private Double aveActivErr; + /** + * 主射线活度值 + */ + @TableField(value = "ACTIV_KEY") + private Double activKey; + /** + * 主射线活度值不确定度 + */ + @TableField(value = "ACTIV_KEY_ERR") + private Double activKeyErr; + /** + * 核素的最小可探测活度 + */ + @TableField(value = "MDA") + private String mda; + /** + * 核素的最小可探测活度不确定度 + */ + @TableField(value = "MDA_ERR") + private Double mdaErr; + /** + * 核素识别标志 + */ + @TableField(value = "NID_FLAG") + private Integer nidFlag; + + @TableField(value = "ACTIV_DECAY") + private Double activDecay; + + @TableField(value = "ACTIV_DECAY_ERR") + private Double activDecayErr; + /** + * 符合相加校正因子(无设为1) + */ + @TableField(value = "CSC_RATIO") + private Double cscRatio; + /** + * 符合相加校正因子不确定度(无设为0) + */ + @TableField(value = "CSC_RATIO_ERR") + private Double cscRatioErr; + /** + * 活度是否经过符合相加校正 + */ + @TableField(value = "CSC_MOD_FLAG") + private Integer cscModFlag; + + @TableField(value = "MODDATE") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date moddate; + + @TableField(value = "MDC") + private String mdc; + + @TableField(value = "CONCENTRATION") + private String concentration; + + @TableField(value = "KEY_ENERGY") + private String keyEnergy; + + @TableField(value = "KEY_YIELD") + private String keyYield; + +} \ No newline at end of file diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnauto/GardsXeResults.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnauto/GardsXeResults.java new file mode 100644 index 0000000..fc99ec2 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnauto/GardsXeResults.java @@ -0,0 +1,64 @@ +package org.jeecg.modules.base.entity.rnauto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * 存储β-γ符合谱最终分析结果。 + */ +@Data +@TableName("RNAUTO.GARDS_XE_RESULTS") +public class GardsXeResults implements Serializable { + + /** + * 样品id + */ + @TableField(value = "SAMPLE_ID") + private Integer sampleId; + /** + * 分析ID号 + */ + @TableField(value = "IDANALYSIS") + private Integer idAnalysis; + /** + * 核素名称 + */ + @TableField(value = "NUCLIDE_NAME") + private String nuclideName; + /** + * 感兴趣区活度浓度 + */ + @TableField(value = "CONC") + private Double conc; + /** + * 感兴趣区活度浓度不确定度 + */ + @TableField(value = "CONC_ERR") + private Double concErr; + /** + * 感兴趣区MDC + */ + @TableField(value = "MDC") + private Double mdc; + /** + * 感兴趣区LC + */ + @TableField(value = "LC") + private Double lc; + /** + * 感兴趣区识别标示;1:识别到,0,未识别到 + */ + @TableField(value = "NID_FLAG") + private Integer nidFlag; + + @TableField(value = "MODDATE") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date moddate; +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnman/GardsNuclIded.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnman/GardsNuclIded.java new file mode 100644 index 0000000..a432abe --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnman/GardsNuclIded.java @@ -0,0 +1,118 @@ +package org.jeecg.modules.base.entity.rnman; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * 存储gamma谱中识别到的核素计算结果。 + */ +@Data +@TableName("RNMAN.GARDS_NUCL_IDED") +public class GardsNuclIded implements Serializable { + + /** + * 样品id + */ + @TableField(value = "SAMPLE_ID") + private Integer sampleId; + /** + * 分析ID号 + */ + @TableField(value = "IDANALYSIS") + private Integer idAnalysis; + /** + * 核素名称 + */ + @TableField(value = "NUCLIDENAME") + private String nuclideName; + /** + * 核素类型 + */ + @TableField(value = "TYPE") + private String type; + /** + * 核素半衰期 + */ + @TableField(value = "HALFLIFE") + private String halflife; + /** + * 平均活度值 + */ + @TableField(value = "AVE_ACTIV") + private String aveActiv; + /** + * 平均活度值不确定度 + */ + @TableField(value = "AVE_ACTIV_ERR") + private Double aveActivErr; + /** + * 主射线活度值 + */ + @TableField(value = "ACTIV_KEY") + private Double activKey; + /** + * 主射线活度值不确定度 + */ + @TableField(value = "ACTIV_KEY_ERR") + private Double activKeyErr; + /** + * 核素的最小可探测活度 + */ + @TableField(value = "MDA") + private String mda; + /** + * 核素的最小可探测活度不确定度 + */ + @TableField(value = "MDA_ERR") + private Double mdaErr; + /** + * 核素识别标志 + */ + @TableField(value = "NID_FLAG") + private Integer nidFlag; + + @TableField(value = "ACTIV_DECAY") + private Double activDecay; + + @TableField(value = "ACTIV_DECAY_ERR") + private Double activDecayErr; + /** + * 符合相加校正因子(无设为1) + */ + @TableField(value = "CSC_RATIO") + private Double cscRatio; + /** + * 符合相加校正因子不确定度(无设为0) + */ + @TableField(value = "CSC_RATIO_ERR") + private Double cscRatioErr; + /** + * 活度是否经过符合相加校正 + */ + @TableField(value = "CSC_MOD_FLAG") + private Integer cscModFlag; + + @TableField(value = "MODDATE") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date moddate; + + @TableField(value = "MDC") + private String mdc; + + @TableField(value = "CONCENTRATION") + private String concentration; + + @TableField(value = "KEY_ENERGY") + private String keyEnergy; + + @TableField(value = "KEY_YIELD") + private String keyYield; +} diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnman/GardsXeResults.java b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnman/GardsXeResults.java new file mode 100644 index 0000000..a5ff2e0 --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/entity/rnman/GardsXeResults.java @@ -0,0 +1,65 @@ +package org.jeecg.modules.base.entity.rnman; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * 存储β-γ符合谱最终分析结果。 + */ +@Data +@TableName("RNMAN.GARDS_XE_RESULTS") +public class GardsXeResults implements Serializable { + + /** + * 样品id + */ + @TableField(value = "SAMPLE_ID") + private Integer sampleId; + /** + * 分析ID号 + */ + @TableField(value = "IDANALYSIS") + private Integer idAnalysis; + /** + * 核素名称 + */ + @TableField(value = "NUCLIDE_NAME") + private String nuclideName; + /** + * 感兴趣区活度浓度 + */ + @TableField(value = "CONC") + private Double conc; + /** + * 感兴趣区活度浓度不确定度 + */ + @TableField(value = "CONC_ERR") + private Double concErr; + /** + * 感兴趣区MDC + */ + @TableField(value = "MDC") + private Double mdc; + /** + * 感兴趣区LC + */ + @TableField(value = "LC") + private Double lc; + /** + * 感兴趣区识别标示;1:识别到,0,未识别到 + */ + @TableField(value = "NID_FLAG") + private Integer nidFlag; + + @TableField(value = "MODDATE") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date moddate; +} diff --git a/jeecg-module-data-analyze/pom.xml b/jeecg-module-data-analyze/pom.xml index 84d23a2..d624bf2 100644 --- a/jeecg-module-data-analyze/pom.xml +++ b/jeecg-module-data-analyze/pom.xml @@ -23,5 +23,23 @@ jeecg-boot-base-core ${jeecgboot.version} + + io.swagger + swagger-annotations + 1.6.6 + compile + + + junit + junit + test + + + io.swagger + swagger-annotations + 1.6.6 + compile + + \ No newline at end of file diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/controller/DataAnalysisController.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/controller/DataAnalysisController.java new file mode 100644 index 0000000..cb8e3d2 --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/controller/DataAnalysisController.java @@ -0,0 +1,130 @@ +package org.jeecg.controller; + + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.util.DateUtils; +import org.jeecg.service.ISampleStatAnalysisService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDate; +import java.util.Date; +import java.util.Objects; + +@RestController +@RequestMapping("dataAnalysis") +@Api(value = "数据分析", tags = "数据分析") +public class DataAnalysisController { + @Autowired + private ISampleStatAnalysisService sampleStatAnalysisService; + + /*** 样品监测结果回放 + * + * @param sampleType + * @param dataSource + * @param startDate + * @param endDate + * @return + */ + @GetMapping("/getSampleMonitorResult") + @ApiOperation(value = "样品监测结果回放", notes = "样品监测结果回放") + public Result getSampleMonitorResult(String sampleType, Integer dataSource, @RequestParam("startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate, + @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) { + + return sampleStatAnalysisService.getSampleMonitorResult(sampleType, dataSource, startDate, endDate); + } + + /*** 样品统计分析 + * + * @param station + * @param dataSource + * @param startDate + * @param endDate + * @return + */ + @GetMapping("/getSampleStatAnalysis") + @ApiOperation(value = "样品统计分析", notes = "样品统计分析") + public Result getSampleStatAnalysis(String station, Integer dataSource, @RequestParam("startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate, + @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) { + return sampleStatAnalysisService.getSampleStatAnalysis(station, dataSource, startDate, endDate); + + } + + /*** 样品等级时序分析 + * 样品等级时序分析 + * @param sampleType 样品类型 + * @param station 台站编码 + * @param dataSource 数据源 + * @param startDate 开始时间 + * @param endDate 结束时间 + * @return 返回样品等级信息 + */ + @GetMapping("/getSampleGradeAnalysis") + @ApiOperation(value = "样品等级时序分析", notes = "样品等级时序分析") + public Result getSampleGradeAnalysis(String sampleType, String station, Integer dataSource, @RequestParam("startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate, + @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) { + Result result = sampleStatAnalysisService.getSampleGradeAnalysis(sampleType, station, startDate, endDate, dataSource); + + return result; + } + + /*** 样品活度浓度区间频率分析 + * + * @param sampleType 样品类型-颗粒物、气体 + * @param station 台站编码 + * @param nuclideName 核素名称 + * @param dataSource 数据源 + * @param startDate 开始时间 + * @param endDate 结束时间 + * @return 返回样品获取浓度区间信息 + */ + @GetMapping("/getActConcIntvlAnalysis") + @ApiOperation(value = "样品活度浓度区间频率分析", notes = "样品活度浓度区间频率分析") + public Result getSampleActConcIntvlAnalysis(String sampleType, String station, String nuclideName, Integer dataSource, @RequestParam("startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate, + @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) { + + return sampleStatAnalysisService.getSampleActConcIntvlAnalysis(sampleType, station, nuclideName, dataSource, startDate, endDate); + } + + /*** 样品活度浓度时序分析 + * + * @param sampleType 样品类型-颗粒物、气体 + * @param station 台站编码 + * @param nuclideName 核素名称 + * @param dataSource 数据源 + * @param startDate 开始时间 + * @param endDate 结束时间 + * @return 返回样品获取浓度时序信息 + */ + @GetMapping("/getActConcTimeSeqAnalysis") + @ApiOperation(value = "样品活度浓度时序分析", notes = "样品活度浓度时序分析") + public Result getSampleActConcTimeSeqAnalysis(String sampleType, String station, String nuclideName, Integer dataSource, @RequestParam("startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate, + @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) { + return sampleStatAnalysisService.getSampleActConcTimeSeqAnalysis(sampleType, station, nuclideName, dataSource, startDate, endDate); + } + + /*** 核素活度浓度对比分析 + * + * @param sampleType + * @param stationIds + * @param nuclideName + * @param dataSource + * @param startDate + * @param endDate + * @return + */ + @GetMapping("/getNuclideActivityConcAnalyze") + @ApiOperation(value = "核素活度浓度对比分析", notes = "核素活度浓度对比分析") + public Result getNuclideActivityConcAnalyze(String sampleType, Integer[] stationIds, String nuclideName, Integer dataSource, @RequestParam("startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate, + @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) { + return sampleStatAnalysisService.getNuclideActivityConcAnalyze(sampleType, stationIds, nuclideName, dataSource, startDate, endDate); + + } + +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/GardsThresholdResultHis.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/GardsThresholdResultHis.java new file mode 100644 index 0000000..90210cd --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/GardsThresholdResultHis.java @@ -0,0 +1,18 @@ +package org.jeecg.entity; + +import lombok.Data; + +import java.util.Date; + +@Data +public class GardsThresholdResultHis { + private String id; + private String stationId; + private String nuclideName; + private double thresholdValue; + private double median; + private double percentile25; + private double percentile75; + private Date calculationTime; + private Long idAnalysis; +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/NuclideActConcIntvl.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/NuclideActConcIntvl.java new file mode 100644 index 0000000..c8d1e3d --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/NuclideActConcIntvl.java @@ -0,0 +1,65 @@ +package org.jeecg.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; +@Data +public class NuclideActConcIntvl { + + /** 样品ID + * + */ + private Integer sampleId; + + /**样品类型 + * 系统类型(P : particulate; B :gas with 3-D β-γ coincidence detection; G :all other gas systems (high-resolution + * γ-spectrometry or 2-D β-γ coincidence + * detection)) + */ + private String sampleType; + + /** 台站编码 + * + */ + private Integer stationId; + + /**数据源 + * + */ + private Integer dataSource; + + /** MDC + * + */ + private Double mdc; + + /** 活度浓度 + * + */ + private Double conc; + /** 收集停止时间 + * + */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date collectStop; + /** + * 活度值不确定度 + */ + private Double concErr; + + /** + * 样品处理状态 + */ + + private String status; + + /** + * 核素名称 + */ + private String nuclideName; + +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/SampleGeadingData.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/SampleGeadingData.java new file mode 100644 index 0000000..fb49498 --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/SampleGeadingData.java @@ -0,0 +1,27 @@ +package org.jeecg.entity; + +import lombok.Data; + +import java.util.Date; + +@Data +public class SampleGeadingData { + + /** + * 样品ID + */ + private Integer sampleId; + /** + * 采集停止时间 + */ + private Date collectStop; + /** + * 级别 + */ + private Integer grading; + /** + * 阈值 + */ + private Double threshold ; + +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/SampleLevelData.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/SampleLevelData.java new file mode 100644 index 0000000..8de079b --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/SampleLevelData.java @@ -0,0 +1,24 @@ +package org.jeecg.entity; + +import lombok.Data; + +import java.util.Date; + +@Data +public class SampleLevelData { + + /** + * 样品ID + */ + private Integer sampleId; + /** + * 采集停止时间 + */ + private Date collectStop; + /** + * 级别 + */ + private Integer category; + + +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/StationInfoData.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/StationInfoData.java new file mode 100644 index 0000000..2a44929 --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/StationInfoData.java @@ -0,0 +1,48 @@ +package org.jeecg.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +@Data +public class StationInfoData implements Serializable { + /** + * 样品ID + */ + private Integer sampleId; + /** + * 采集停止时间 + */ + private Date collectStop; + /** + * 级别 + */ + private Integer category; + /** + * 阈值 + */ + private Double threshold; + + private String stationCode; + private String countryCode; + + private String type; + + private String lon; + + private String lat; + + private String description; + + private String status; + + +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/StationInfoQueryResult.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/StationInfoQueryResult.java new file mode 100644 index 0000000..46096c0 --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/StationInfoQueryResult.java @@ -0,0 +1,25 @@ +package org.jeecg.entity; + +import lombok.Data; + +import java.util.List; + +@Data +public class StationInfoQueryResult { + + private String stationCode; + private Integer stationId; + private String countryCode; + + private String type; + + private String lon; + + private String lat; + + private String description; + + private String status; + + List SampleLevelDataList; +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/ThresholdMetric.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/ThresholdMetric.java new file mode 100644 index 0000000..5df1e16 --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/entity/ThresholdMetric.java @@ -0,0 +1,11 @@ +package org.jeecg.entity; + +import lombok.Data; + +@Data +public class ThresholdMetric { + private Integer stationId; + private Integer sampleId; + private String nuclideName; + private String concentration; +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/mapper/GardsSampleStatAnalysisMapper.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/mapper/GardsSampleStatAnalysisMapper.java new file mode 100644 index 0000000..438c9de --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/mapper/GardsSampleStatAnalysisMapper.java @@ -0,0 +1,225 @@ +package org.jeecg.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.jeecg.entity.*; +import org.jeecg.modules.base.entity.original.GardsSampleData; + +import java.util.List; + +@Mapper +public interface GardsSampleStatAnalysisMapper extends BaseMapper { + + List getSampleStatAnalysis(String station, String startDate, String endDate); + + List selectByStationIds(@Param("stationIds") List stationIds, @Param("startTime") String startTime, @Param("endTime") String endTime); + + //region 样品等级时序分析 + + + List getSampleGradeAnalysis(String sampleType, String station, + @Param("startTime") String startTime, @Param("endTime") String endTime, Integer dataSource); + + List getRnAutoSampleGradeAnalysis(String sampleType, String station, + @Param("startTime") String startTime, @Param("endTime") String endTime); + + List getRnManSampleGradeAnalysis(String sampleType, String station, + @Param("startTime") String startTime, @Param("endTime") String endTime); + + //endregion + + /*** 获取样品类型P中元素的浓度活度、MDC信息 + * 获取样品中元素的浓度活度、MDC信息 + * @param station 台站编码 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 返回List + */ + List getSamplePNuclideActConcIntvl(String station, @Param("startTime") String startTime, @Param("endTime") String endTime); + + //region 获取样品的级别和阈值 + + List getRnAutoSampleLevel(String station, @Param("startTime") String startTime, @Param("endTime") String endTime); + + List getRnManSampleLevel(String station, @Param("startTime") String startTime, @Param("endTime") String endTime); + + //endregion + + //region RNAUTO 获取样品中元素的浓度活度、MDC信息 + + /*** 获取样品中元素的浓度活度、MDC信息 + * 查询RNAUTO.GARDS_NUCL_IDED中的活度浓度、MDC信息 + * @param station 台站编码 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 返回List + */ + List getRnautoPNuclideActConcIntvl(String sampleType,String station,String nuclideName, @Param("startTime") String startTime, @Param("endTime") String endTime); + + /*** 获取样品中元素的浓度活度、MDC信息 + * 查询RNAUTO.GARDS_XE_RESULTS中的活度浓度、MDC信息 + * @param station + * @param startTime + * @param endTime + * @return + */ + List getRnautoNuclideActConcIntvl(String sampleType,String station,String nuclideName, @Param("startTime") String startTime, @Param("endTime") String endTime); + + + //endregion + + //region RNMAN 获取样品中元素的浓度活度、MDC信息 + + /*** 获取样品中元素的浓度活度、MDC信息 + * 查询RNAUTO.GARDS_NUCL_IDED中的活度浓度、MDC信息 + * @param station 台站编码 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 返回List + */ + List getRnmanPNuclideActConcIntvl(String sampleType,String station,String nuclideName, @Param("startTime") String startTime, @Param("endTime") String endTime); + + /*** 获取样品中元素的浓度活度、MDC信息 + * 查询RNAUTO.GARDS_XE_RESULTS中的活度浓度、MDC信息 + * @param station + * @param startTime + * @param endTime + * @return + */ + List getRnmanNuclideActConcIntvl(String sampleType,String station,String nuclideName, @Param("startTime") String startTime, @Param("endTime") String endTime); + + //endregion + + + //region 样品统计分析 + + /** + * RnAuto--获取样品中识别到的核素集合 + */ + + List getRnAutoIdentifiedNuclides(String station, @Param("startTime") String startTime, @Param("endTime") String endTime); + + /** + * RnAuto-- 核素等级时序分析 + */ + + List getRnAutoNuclideTimeSeriesAnalysis(String station, @Param("startTime") String startTime, @Param("endTime") String endTime); + + /** + * RnMan--获取样品中识别到的核素集合 + */ + List getRnManIdentifiedNuclides(String station, @Param("startTime") String startTime, @Param("endTime") String endTime); + + /** + * RnMan--核素等级时序分析 + * + * @return List + */ + List getRnManNuclideTimeSeriesAnalysis(String station, @Param("startTime") String startTime, @Param("endTime") String endTime); + + + + /** + * 精确查询(单个站点 + 单个核素) + * @param stationId 站点ID (必填) + * @param nuclideName 核素名称 (必填) + * @return 匹配的记录列表 + */ + List selectByStationAndNuclide( + @Param("schemaName") String schemaName, + @Param("stationId") Integer stationId, + @Param("nuclideName") String nuclideName, + @Param("startTime") String startTime, + @Param("endTime") String endTime + ); + + /** + * 多站点 + 多核素查询 + * @param stationIds 站点ID集合 (非空) + * @param nuclideNames 核素名称集合 (非空) + * @return 匹配的记录列表 + */ + List selectByStationsAndNuclides( + @Param("schemaName") String schemaName, + @Param("stationIds") List stationIds, + @Param("nuclideNames") List nuclideNames, + @Param("startTime") String startTime, + @Param("endTime") String endTime + ); + + /** + * 多站点 + 单核素查询 + * @param stationIds 站点ID集合 (非空) + * @param nuclideName 单个核素名称 (必填) + * @return 匹配的记录列表 + */ + List selectByStationsAndNuclide( + @Param("schemaName") String schemaName, + @Param("stationIds") List stationIds, + @Param("nuclideName") String nuclideName, + @Param("startTime") String startTime, + @Param("endTime") String endTime + ); + + /** + * 单站点 + 多核素查询 + * @param stationId 单个站点ID (必填) + * @param nuclideNames 核素名称集合 (非空) + * @return 匹配的记录列表 + */ + List selectByStationAndNuclides( + @Param("schemaName") String schemaName, + @Param("stationId") Integer stationId, + @Param("nuclideNames") List nuclideNames, + @Param("startTime") String startTime, + @Param("endTime") String endTime + + ); + + /** + * 动态条件查询(所有参数均可为空) + * @param stationIds 站点ID集合 (可选) + * @param nuclideNames 核素名称集合 (可选) + * @param startTime 开始时间 (可选) + * @param endTime 结束时间 (可选) + * @return 匹配的记录列表 + */ + List selectByCondition( + @Param("schemaName") String schemaName, + @Param("stationIds") List stationIds, + @Param("nuclideNames") List nuclideNames, + @Param("startTime") String startTime, + @Param("endTime") String endTime + ); + + + + + + + + + + + + //endregion + + + //region 核素活度浓度对比分析 + List getRnAutoAnalyzeNuclideActivityConc(String sampleType, String nuclideName, @Param("stationIds") Integer[] stationIds, @Param("startTime") String startTime, @Param("endTime") String endTime); + + List getRnManAnalyzeNuclideActivityConc(String sampleType, String nuclideName, @Param("stationIds") Integer[] stationIds, @Param("startTime") String startTime, @Param("endTime") String endTime); + //endregion + + //region 样品监测结果 + List getRnAutoSampleResult(String sampleType, @Param("startTime") String startTime, @Param("endTime") String endTime); + + List getRnManSampleResult(String sampleType, @Param("startTime") String startTime, @Param("endTime") String endTime); + + + + //endregion + + +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/mapper/xml/GardsSampleStatAnalysisMapper.xml b/jeecg-module-data-analyze/src/main/java/org/jeecg/mapper/xml/GardsSampleStatAnalysisMapper.xml new file mode 100644 index 0000000..948020f --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/mapper/xml/GardsSampleStatAnalysisMapper.xml @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/service/ISampleStatAnalysisService.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/service/ISampleStatAnalysisService.java new file mode 100644 index 0000000..8f49104 --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/service/ISampleStatAnalysisService.java @@ -0,0 +1,27 @@ +package org.jeecg.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.base.entity.original.GardsSampleData; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.Date; +import java.util.List; + +public interface ISampleStatAnalysisService extends IService { + + Result getSampleMonitorResult(String sampleType, Integer dataSource, Date startDate, Date endDate); + + Result getSampleStatAnalysis(String station, Integer dataSource, Date startDate, Date endDate); + + Result getSampleGradeAnalysis(String sampleType, String station, Date startDate, Date endDate, Integer dataSource); + + Result getSampleActConcIntvlAnalysis(String sampleType, String station, String nuclideName, Integer dataSource, Date startDate, Date endDate); + + + Result getSampleActConcTimeSeqAnalysis(String sampleType, String station, String nuclideName, Integer dataSource, Date startDate, Date endDate); + + Result getNuclideActivityConcAnalyze(String sampleType, Integer[] stationIds, String nuclideName, Integer dataSource, Date startDate, Date endDate); + +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/service/impl/SampleStatAnalysisService.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/service/impl/SampleStatAnalysisService.java new file mode 100644 index 0000000..fd781a8 --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/service/impl/SampleStatAnalysisService.java @@ -0,0 +1,432 @@ +package org.jeecg.service.impl; + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.util.DateUtils; +import org.jeecg.entity.GardsThresholdResultHis; +import org.jeecg.modules.base.entity.original.GardsSampleData; +import org.jeecg.entity.NuclideActConcIntvl; +import org.jeecg.entity.SampleLevelData; +import org.jeecg.entity.StationInfoData; +import org.jeecg.mapper.GardsSampleStatAnalysisMapper; +import org.jeecg.service.ISampleStatAnalysisService; +import org.jeecg.util.DistributionAnalysisToolkit; +import org.springframework.stereotype.Service; + +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + + +@Service +@DS("ora") +public class SampleStatAnalysisService extends ServiceImpl implements ISampleStatAnalysisService { + + + public Result getSampleMonitorResult(String sampleType, Integer dataSource, Date startDate, Date endDate) { + Result result = new Result(); + //声明返回用的结果map + Map resultMap = new HashMap<>(); + List StationInfoDataList = new ArrayList<>(); + + //region 局部变量 + if (StringUtils.isBlank(sampleType)) { + result.error500("SampleType Code cannot be null"); + return result; + } + if (Objects.isNull(startDate)) { + result.error500("The start time cannot be empty"); + return result; + } + String startTime = DateUtils.formatDate(startDate, "yyyy-MM-dd") + " 00:00:00"; + if (Objects.isNull(endDate)) { + result.error500("The end time cannot be empty"); + return result; + } + String endTime = DateUtils.formatDate(endDate, "yyyy-MM-dd") + " 23:59:59"; + //endregion + + switch (dataSource) { + case 1: + StationInfoDataList = this.baseMapper.getRnAutoSampleResult(sampleType, startTime, endTime); + + break; + case 2: + StationInfoDataList = this.baseMapper.getRnManSampleResult(sampleType, startTime, endTime); + + break; + } + //时间段内有多少和台站 + + Map> groupedByMonth = StationInfoDataList.stream() + .collect(Collectors.groupingBy(station -> + station.getCollectStop().toInstant() + .atZone(ZoneId.of("UTC")) + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + )); + + + resultMap.put("SampleMonitorResultList", groupedByMonth); + + result.setSuccess(true); + result.setResult(resultMap); + + return result; + } + + + /*** 样品统计分析 + * 样品统计分析 + * @param stationCode + * @param startDate + * @param endDate + * @return + */ + @Override + public Result getSampleStatAnalysis(String stationCode, Integer dataSource, Date startDate, Date endDate) { + //声明返回用的结果map + Map resultMap = new HashMap<>(); + List nuclideActConcIntvlList = new ArrayList<>(); + List sampleLevelDataList = new ArrayList<>(); + List thresholdResultHisDataList = new ArrayList<>(); + + String schemaName = dataSource == 1 ? "RNAUTO" : "RNMAN"; + //region 局部变量 + Result result = new Result(); + if (StringUtils.isBlank(stationCode)) { + result.error500("Station Code cannot be null"); + return result; + } + if (Objects.isNull(startDate)) { + result.error500("The start time cannot be empty"); + return result; + } + String startTime = DateUtils.formatDate(startDate, "yyyy-MM-dd") + " 00:00:00"; + if (Objects.isNull(endDate)) { + result.error500("The end time cannot be empty"); + return result; + } + String endTime = DateUtils.formatDate(endDate, "yyyy-MM-dd") + " 23:59:59"; + //endregion + switch (dataSource) { + //RNAUTO + case 1: + //获取样品中识别到的核素集合 + nuclideActConcIntvlList = this.baseMapper.getRnAutoIdentifiedNuclides(stationCode, startTime, endTime); + + //核素等级时序分析 + sampleLevelDataList = this.baseMapper.getRnAutoNuclideTimeSeriesAnalysis(stationCode, startTime, endTime); + break; + //RNMAN + case 2: + //获取样品中识别到的核素集合 + nuclideActConcIntvlList = this.baseMapper.getRnManIdentifiedNuclides(stationCode, startTime, endTime); + + //核素等级时序分析 + sampleLevelDataList = this.baseMapper.getRnManNuclideTimeSeriesAnalysis(stationCode, startTime, endTime); + break; + } + //key=核素名称,value=获取样品中识别到的核素集合 + Map> groupedByNuclideName = nuclideActConcIntvlList.stream() + .filter(p->p.getNuclideName()!=null) + .collect(Collectors.groupingBy(NuclideActConcIntvl::getNuclideName)); + //查询级别 getSample + List nuclideNames = new ArrayList<>(groupedByNuclideName.keySet()); + //通过台站ID、核素名称查找阈值 + thresholdResultHisDataList = this.baseMapper.selectByStationAndNuclides(schemaName, Integer.valueOf(stationCode), nuclideNames, startTime, endTime); + + resultMap.put("nuclideActConcIntvlList", groupedByNuclideName); + resultMap.put("sampleLevelDataList", sampleLevelDataList); + resultMap.put("thresholdResultHisDataList", thresholdResultHisDataList); + result.setSuccess(true); + result.setResult(resultMap); + + return result; + } + + /** + * 获取指定时间范围内的样品等级 + * + * + */ + @Override + public Result getSampleGradeAnalysis(String sampleType, String station, Date startDate, Date endDate, Integer dataSource) { + + //声明返回用的结果map + Map resultMap = new HashMap<>(); + List sampleDataList = new ArrayList<>(); + //region 局部变量 + Result result = new Result(); + if (StringUtils.isBlank(sampleType)) { + result.error500("SampleType Code cannot be null"); + return result; + } + if (StringUtils.isBlank(station)) { + result.error500("Station Code cannot be null"); + return result; + } + if (Objects.isNull(startDate)) { + result.error500("The start time cannot be empty"); + return result; + } + String startTime = DateUtils.formatDate(startDate, "yyyy-MM-dd") + " 00:00:00"; + if (Objects.isNull(endDate)) { + result.error500("The end time cannot be empty"); + return result; + } + String endTime = DateUtils.formatDate(endDate, "yyyy-MM-dd") + " 23:59:59"; + //endregion + switch (dataSource) { + case 1: + sampleDataList = this.baseMapper.getRnAutoSampleGradeAnalysis(sampleType, station, startTime, endTime); + + break; + case 2: + sampleDataList = this.baseMapper.getRnManSampleGradeAnalysis(sampleType, station, startTime, endTime); + break; + + } + + resultMap.put("sampleDataList", sampleDataList); + result.setSuccess(true); + result.setResult(resultMap); + + + return result; + } + + /*** 样品活度浓度区间频率分析 + * 样品活度浓度区间频率分析 + * @param sampleType 样品类型 + * @param station 台站编码 + * @param nuclideName 核素名称 + * @param dataSource 数据源 + * @param startDate 开始时间 + * @param endDate 结束时间 + * @return 返回样品活度浓度区间信息 + */ + @Override + public Result getSampleActConcIntvlAnalysis(String sampleType, String station, String nuclideName, Integer dataSource, Date startDate, Date endDate) { + //声明返回用的结果map + Map resultMap = new HashMap<>(); + List nuclideActConcIntvls = new ArrayList<>(); + //region 局部变量 + Result result = new Result(); + if (StringUtils.isBlank(sampleType)) { + result.error500("SampleType Code cannot be null"); + return result; + } + if (StringUtils.isBlank(nuclideName)) { + result.error500("nuclideName Code cannot be null"); + return result; + } + if (StringUtils.isBlank(station)) { + result.error500("Station Code cannot be null"); + return result; + } + if (Objects.isNull(startDate)) { + result.error500("The start time cannot be empty"); + return result; + } + String startTime = DateUtils.formatDate(startDate, "yyyy-MM-dd") + " 00:00:00"; + if (Objects.isNull(endDate)) { + result.error500("The end time cannot be empty"); + return result; + } + String endTime = DateUtils.formatDate(endDate, "yyyy-MM-dd") + " 23:59:59"; + //endregion + + //根据数据源、样品类型查询样品的浓度 + switch (sampleType) { + case "P": + switch (dataSource) { + //RNAUTO + case 1: + nuclideActConcIntvls = this.baseMapper.getRnautoPNuclideActConcIntvl(sampleType, station, nuclideName, startTime, endTime); + break; + //RNMAN + case 2: + nuclideActConcIntvls = this.baseMapper.getRnautoNuclideActConcIntvl(sampleType, station, nuclideName, startTime, endTime); + break; + } + break; + case "B": + switch (dataSource) { + case 1: + nuclideActConcIntvls = this.baseMapper.getRnmanPNuclideActConcIntvl(sampleType, station, nuclideName, startTime, endTime); + break; + case 2: + nuclideActConcIntvls = this.baseMapper.getRnmanNuclideActConcIntvl(sampleType, station, nuclideName, startTime, endTime); + break; + + } + break; + + } + + //获取浓度出现的次数 + //获取浓度值集合 + List data = DistributionAnalysisToolkit.convertConcToDoubleList(nuclideActConcIntvls); + // 设置区间参数 + double start = 0; // 区间起始值 + double step = 200; // 区间步长(宽度) + + + // 1. 区间统计 + List stats = DistributionAnalysisToolkit.calculateIntervalStats(data, start, step); + // 3. 累积分布函数 + List cdfPoints = DistributionAnalysisToolkit.calculateCDF(data); + // 4. 核密度估计 + List kdePoints = DistributionAnalysisToolkit.autoKDE(data, DistributionAnalysisToolkit.GAUSSIAN_KERNEL); + //获取所有浓度的累积 + List cumulative = DistributionAnalysisToolkit.cumulativeSum(data); + //获取95%累积线 + double percentile95 = DistributionAnalysisToolkit.calculate95thPercentile(data); + + resultMap.put("stats", stats); + resultMap.put("cdfPoints", cdfPoints); + resultMap.put("kdePoints", kdePoints); + resultMap.put("cumulative", cumulative); + resultMap.put("percentile95", percentile95); + result.setSuccess(true); + result.setResult(resultMap); + return result; + } + + /*** 核素活度浓度时序分析 + * 核素活度浓度时序分析 + * @param sampleType 样品类型 + * @param station 台站编码 + * @param nuclideName 核素名 + * @param dataSource 数据源 + * @param startDate 开始时间 + * @param endDate 结束时间 + * @return 返回核素活度浓度信息 + */ + @Override + public Result getSampleActConcTimeSeqAnalysis(String sampleType, String station, String nuclideName, Integer dataSource, Date startDate, Date endDate) { + Result result = new Result(); + //声明返回用的结果map + Map resultMap = new HashMap<>(); + //region 局部变量 + + if (StringUtils.isBlank(sampleType)) { + result.error500("SampleType Code cannot be null"); + return result; + } + if (StringUtils.isBlank(nuclideName)) { + result.error500("nuclideName Code cannot be null"); + return result; + } + if (StringUtils.isBlank(station)) { + result.error500("Station Code cannot be null"); + return result; + } + if (Objects.isNull(startDate)) { + result.error500("The start time cannot be empty"); + return result; + } + String startTime = DateUtils.formatDate(startDate, "yyyy-MM-dd") + " 00:00:00"; + if (Objects.isNull(endDate)) { + result.error500("The end time cannot be empty"); + return result; + } + String endTime = DateUtils.formatDate(endDate, "yyyy-MM-dd") + " 23:59:59"; + //endregion + //获取样品阈值级别和阈值 + List sampleDatas = new ArrayList<>(); + //核素的阈值 + List thresholdResultHisList = new ArrayList<>(); + List nuclideActConcIntvls = new ArrayList<>(); + nuclideActConcIntvls = switch (sampleType) { + case "P" -> { + sampleDatas = this.baseMapper.getRnAutoSampleLevel(station, startTime, endTime); + yield switch (dataSource) { + //RNAUTO + case 1 -> + this.baseMapper.getRnautoPNuclideActConcIntvl(sampleType, station, nuclideName, startTime, endTime); + //RNMAN + case 2 -> + this.baseMapper.getRnautoNuclideActConcIntvl(sampleType, station, nuclideName, startTime, endTime); + default -> nuclideActConcIntvls; + }; + } + case "B" -> { + sampleDatas = this.baseMapper.getRnManSampleLevel(station, startTime, endTime); + yield switch (dataSource) { + case 1 -> + this.baseMapper.getRnmanPNuclideActConcIntvl(sampleType, station, nuclideName, startTime, endTime); + case 2 -> + this.baseMapper.getRnmanNuclideActConcIntvl(sampleType, station, nuclideName, startTime, endTime); + default -> nuclideActConcIntvls; + }; + } + default -> nuclideActConcIntvls; + }; + String schemaName = dataSource == 1 ? "RNAUTO" : "RNMAN"; + + thresholdResultHisList = this.baseMapper.selectByCondition(schemaName, Arrays.asList(Integer.valueOf(station)) + , Arrays.asList(nuclideName), startTime, endTime); + resultMap.put("sampleDataList", sampleDatas); + resultMap.put("nuclideInfoList", nuclideActConcIntvls); + resultMap.put("thresholdResultHisList", thresholdResultHisList); + + result.setSuccess(true); + result.setResult(resultMap); + return result; + } + + /*** 核素活度浓度对比分析 + * 核素活度浓度对比分析 + * @param sampleType 样品类型 + * @param stationIds 台站ID集合 + * @param nuclideName 核素名 + * @param dataSource 数据源 + * @param startDate 开始时间 + * @param endDate 结束时间 + * @return + */ + public Result getNuclideActivityConcAnalyze(String sampleType, Integer[] stationIds, String nuclideName, Integer dataSource, Date startDate, Date endDate) { + + Result result = new Result(); + Map resultMap = new HashMap<>(); + List nuclideActConcIntvls = new ArrayList<>(); + //region 局部变量 + if (Objects.isNull(startDate)) { + result.error500("The start time cannot be empty"); + return result; + } + String startTime = DateUtils.formatDate(startDate, "yyyy-MM-dd") + " 00:00:00"; + if (Objects.isNull(endDate)) { + result.error500("The end time cannot be empty"); + return result; + } + String endTime = DateUtils.formatDate(endDate, "yyyy-MM-dd") + " 23:59:59"; + + if (Objects.isNull(stationIds)) { + result.setSuccess(true); + result.setResult(Collections.emptyList()); + return result; + } + //endregion + switch (dataSource) { + case 1: + nuclideActConcIntvls = this.baseMapper.getRnAutoAnalyzeNuclideActivityConc(sampleType, nuclideName, stationIds, startTime, endTime); + break; + case 2: + nuclideActConcIntvls = this.baseMapper.getRnManAnalyzeNuclideActivityConc(sampleType, nuclideName, stationIds, startTime, endTime); + break; + + } + resultMap.put("nuclideInfoList", nuclideActConcIntvls); + result.setSuccess(true); + result.setResult(resultMap); + + return result; + } + + +} diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/util/DistributionAnalysisToolkit.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/util/DistributionAnalysisToolkit.java new file mode 100644 index 0000000..28a3954 --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/util/DistributionAnalysisToolkit.java @@ -0,0 +1,288 @@ +package org.jeecg.util; + +import org.jeecg.entity.NuclideActConcIntvl; + +import java.util.*; +import java.util.stream.Collectors; + +public class DistributionAnalysisToolkit { + /** + * 区间统计结果 + */ + public static class IntervalStat { + private final String interval; + private final int count; + private final List values; + + public IntervalStat(String interval, int count, List values) { + this.interval = interval; + this.count = count; + this.values = values; + } + + public String getInterval() { return interval; } + public int getCount() { return count; } + public List getValues() { return values; } + } + + /** + * KDE曲线点 + */ + public static class KDEPoint { + private final double x; + private final double density; + + public KDEPoint(double x, double density) { + this.x = x; + this.density = density; + } + + public double getX() { return x; } + public double getDensity() { return density; } + } + + /** + * CDF曲线点 + */ + public static class CDFPoint { + private final double value; + private final double cumulativeProb; + + public CDFPoint(double value, double cumulativeProb) { + this.value = value; + this.cumulativeProb = cumulativeProb; + } + + public double getValue() { return value; } + public double getCumulativeProb() { return cumulativeProb; } + } + /** + * 数据区间统计 + * + * @param data 原始数据 + * @param start 起始值 + * @param step 区间宽度 + * @return 区间统计结果列表 + */ + public static List calculateIntervalStats(List data, double start, double step) { + if (data == null || data.isEmpty()) { + throw new IllegalArgumentException("数据不能为空"); + } + + // 计算结束边界 + double max = Collections.max(data); + double end = Math.ceil(max / step) * step + step; + + // 初始化区间映射 + Map> intervalMap = new TreeMap<>(); + for (double lower = start; lower < end; lower += step) { + double upper = lower + step; + String key = String.format("[%.1f, %.1f)", lower, upper); + intervalMap.put(key, new ArrayList<>()); + } + + // 分配数据到区间 + for (double value : data) { + double lower = Math.floor(value / step) * step; + String key = String.format("[%.1f, %.1f)", lower, lower + step); + intervalMap.get(key).add(value); + } + + // 转换为统计结果对象 + List stats = new ArrayList<>(); + for (Map.Entry> entry : intervalMap.entrySet()) { + stats.add(new IntervalStat(entry.getKey(), entry.getValue().size(), entry.getValue())); + } + + return stats; + } + + + /** + * 计算95%累积线 + * + * @param data 原始数据 + * @return 95%累积线值 + */ + public static double calculate95thPercentile(List data) { + if (data == null || data.isEmpty()) { + throw new IllegalArgumentException("数据不能为空"); + } + + // 排序数据 + List sortedData = new ArrayList<>(data); + Collections.sort(sortedData); + + int n = sortedData.size(); + double position = 0.95 * (n - 1); + + int lowerIndex = (int) Math.floor(position); + int upperIndex = (int) Math.ceil(position); + + if (lowerIndex == upperIndex) { + return sortedData.get(lowerIndex); + } + + // 线性插值 + double lowerValue = sortedData.get(lowerIndex); + double upperValue = sortedData.get(upperIndex); + double fraction = position - lowerIndex; + + return lowerValue + fraction * (upperValue - lowerValue); + } + + + /** + * 计算累积分布函数(CDF) + * + * @param data 原始数据 + * @return CDF点列表 + */ + public static List calculateCDF(List data) { + if (data == null || data.isEmpty()) { + throw new IllegalArgumentException("数据不能为空"); + } + + // 排序数据 + List sortedData = new ArrayList<>(data); + Collections.sort(sortedData); + + // 计算累积分布 + List cdfPoints = new ArrayList<>(); + int n = sortedData.size(); + + for (int i = 0; i < n; i++) { + double value = sortedData.get(i); + double cumulativeProbability = (i + 1.0) / n; + cdfPoints.add(new CDFPoint(value, cumulativeProbability)); + } + + return cdfPoints; + } + + + + /** + * 核函数接口 + */ + @FunctionalInterface + public interface KernelFunction { + double apply(double u); + } + + // 常用核函数实现 + public static final KernelFunction GAUSSIAN_KERNEL = u -> Math.exp(-0.5 * u * u) / Math.sqrt(2 * Math.PI); + public static final KernelFunction EPANECHNIKOV_KERNEL = u -> (Math.abs(u) <= 1) ? 0.75 * (1 - u * u) : 0; + public static final KernelFunction TRIANGULAR_KERNEL = u -> (Math.abs(u) <= 1) ? 1 - Math.abs(u) : 0; + + + + /** + * 使用Silverman规则计算最佳带宽 + */ + public static double calculateBandwidthSilverman(List data) { + int n = data.size(); + if (n <= 1) return 1.0; + + // 计算标准差 + double mean = data.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); + double variance = data.stream() + .mapToDouble(x -> Math.pow(x - mean, 2)) + .average() + .orElse(0.0); + double sigma = Math.sqrt(variance); + + // 计算四分位距(IQR) + List sortedData = new ArrayList<>(data); + Collections.sort(sortedData); + + double q1 = sortedData.get((int) Math.ceil(0.25 * n - 1)); + double q3 = sortedData.get((int) Math.ceil(0.75 * n - 1)); + double iqr = q3 - q1; + + // Silverman规则 + return 0.9 * Math.min(sigma, iqr / 1.34) * Math.pow(n, -0.2); + } + + /** + * 核密度估计 + */ + public static List kernelDensityEstimate( + List data, KernelFunction kernel, double bandwidth) { + + if (data == null || data.isEmpty()) { + throw new IllegalArgumentException("数据不能为空"); + } + + // 计算数据范围 + double min = Collections.min(data); + double max = Collections.max(data); + double range = max - min; + double minX = min - 0.1 * range; + double maxX = max + 0.1 * range; + + // 生成评估点 + int numPoints = 200; + double step = (maxX - minX) / (numPoints - 1); + + List kdePoints = new ArrayList<>(); + int n = data.size(); + + for (int i = 0; i < numPoints; i++) { + double x = minX + i * step; + double sum = 0.0; + + for (double value : data) { + double u = (x - value) / bandwidth; + sum += kernel.apply(u); + } + + double density = sum / (n * bandwidth); + kdePoints.add(new KDEPoint(x, density)); + } + + return kdePoints; + } + + /** + * 自动KDE计算(自动选择带宽) + */ + public static List autoKDE(List data, KernelFunction kernel) { + double bandwidth = calculateBandwidthSilverman(data); + return kernelDensityEstimate(data, kernel, bandwidth); + } + + + + //获取浓度值集合 + public static List convertConcToDoubleList(List nuclideList) { + return nuclideList.stream() // 创建流 + .map(NuclideActConcIntvl::getConc) // 提取conc值 + .collect(Collectors.toList()); // 收集为List + } + //累积和 + public static List cumulativeSum(List data) { + List result = new ArrayList<>(); + double sum = 0.0; + + for (double value : data) { + sum += value; + result.add(sum); + } + + return result; + } + + + + + + + + + + + + + +} diff --git a/jeecg-server-cloud/jeecg-data-analyze-start/src/main/resources/application.yml b/jeecg-server-cloud/jeecg-data-analyze-start/src/main/resources/application.yml new file mode 100644 index 0000000..78dcceb --- /dev/null +++ b/jeecg-server-cloud/jeecg-data-analyze-start/src/main/resources/application.yml @@ -0,0 +1,24 @@ +server: + port: 9002 + +spring: + application: + name: jeecg-data-analyze + 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