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