增加数据分析服务接口

This commit is contained in:
duwenyuan 2025-10-15 15:13:53 +08:00
parent 99da5aaf97
commit 016cb399ef
6 changed files with 1636 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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<GardsSampleData> {
List<GardsSampleData> getSampleStatAnalysis(String station, String startDate, String endDate);
List<ThresholdMetric> selectByStationIds(@Param("stationIds") List<String> stationIds, @Param("startTime") String startTime, @Param("endTime") String endTime);
//region 样品等级时序分析
List<GardsSampleData> getSampleGradeAnalysis(String sampleType, String station,
@Param("startTime") String startTime, @Param("endTime") String endTime, Integer dataSource);
List<SampleLevelData> getRnAutoSampleGradeAnalysis(String sampleType, String station,
@Param("startTime") String startTime, @Param("endTime") String endTime);
List<SampleLevelData> 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<NuclideActConcIntvl>
*/
List<NuclideActConcIntvl> getSamplePNuclideActConcIntvl(String station, @Param("startTime") String startTime, @Param("endTime") String endTime);
//region 获取样品的级别和阈值
List<SampleLevelData> getRnAutoSampleLevel(String station, @Param("startTime") String startTime, @Param("endTime") String endTime);
List<SampleLevelData> 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<NuclideActConcIntvl>
*/
List<NuclideActConcIntvl> 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<NuclideActConcIntvl> 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<NuclideActConcIntvl>
*/
List<NuclideActConcIntvl> 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<NuclideActConcIntvl> getRnmanNuclideActConcIntvl(String sampleType,String station,String nuclideName, @Param("startTime") String startTime, @Param("endTime") String endTime);
//endregion
//region 样品统计分析
/**
* RnAuto--获取样品中识别到的核素集合
*/
List<NuclideActConcIntvl> getRnAutoIdentifiedNuclides(String station, @Param("startTime") String startTime, @Param("endTime") String endTime);
/**
* RnAuto-- 核素等级时序分析
*/
List<SampleLevelData> getRnAutoNuclideTimeSeriesAnalysis(String station, @Param("startTime") String startTime, @Param("endTime") String endTime);
/**
* RnMan--获取样品中识别到的核素集合
*/
List<NuclideActConcIntvl> getRnManIdentifiedNuclides(String station, @Param("startTime") String startTime, @Param("endTime") String endTime);
/**
* RnMan--核素等级时序分析
*
* @return List<SampleLevelData>
*/
List<SampleLevelData> getRnManNuclideTimeSeriesAnalysis(String station, @Param("startTime") String startTime, @Param("endTime") String endTime);
/**
* 精确查询单个站点 + 单个核素
* @param stationId 站点ID (必填)
* @param nuclideName 核素名称 (必填)
* @return 匹配的记录列表
*/
List<GardsThresholdResultHis> 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<GardsThresholdResultHis> selectByStationsAndNuclides(
@Param("schemaName") String schemaName,
@Param("stationIds") List<Integer> stationIds,
@Param("nuclideNames") List<String> nuclideNames,
@Param("startTime") String startTime,
@Param("endTime") String endTime
);
/**
* 多站点 + 单核素查询
* @param stationIds 站点ID集合 (非空)
* @param nuclideName 单个核素名称 (必填)
* @return 匹配的记录列表
*/
List<GardsThresholdResultHis> selectByStationsAndNuclide(
@Param("schemaName") String schemaName,
@Param("stationIds") List<Integer> stationIds,
@Param("nuclideName") String nuclideName,
@Param("startTime") String startTime,
@Param("endTime") String endTime
);
/**
* 单站点 + 多核素查询
* @param stationId 单个站点ID (必填)
* @param nuclideNames 核素名称集合 (非空)
* @return 匹配的记录列表
*/
List<GardsThresholdResultHis> selectByStationAndNuclides(
@Param("schemaName") String schemaName,
@Param("stationId") Integer stationId,
@Param("nuclideNames") List<String> nuclideNames,
@Param("startTime") String startTime,
@Param("endTime") String endTime
);
/**
* 动态条件查询所有参数均可为空
* @param stationIds 站点ID集合 (可选)
* @param nuclideNames 核素名称集合 (可选)
* @param startTime 开始时间 (可选)
* @param endTime 结束时间 (可选)
* @return 匹配的记录列表
*/
List<GardsThresholdResultHis> selectByCondition(
@Param("schemaName") String schemaName,
@Param("stationIds") List<Integer> stationIds,
@Param("nuclideNames") List<String> nuclideNames,
@Param("startTime") String startTime,
@Param("endTime") String endTime
);
//endregion
//region 核素活度浓度对比分析
List<NuclideActConcIntvl> getRnAutoAnalyzeNuclideActivityConc(String sampleType, String nuclideName, @Param("stationIds") Integer[] stationIds, @Param("startTime") String startTime, @Param("endTime") String endTime);
List<NuclideActConcIntvl> getRnManAnalyzeNuclideActivityConc(String sampleType, String nuclideName, @Param("stationIds") Integer[] stationIds, @Param("startTime") String startTime, @Param("endTime") String endTime);
//endregion
//region 样品监测结果
List<StationInfoData> getRnAutoSampleResult(String sampleType, @Param("startTime") String startTime, @Param("endTime") String endTime);
List<StationInfoData> getRnManSampleResult(String sampleType, @Param("startTime") String startTime, @Param("endTime") String endTime);
//endregion
}

View File

@ -0,0 +1,534 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.mapper.GardsSampleStatAnalysisMapper">
<select id="getSampleStatAnalysis" resultType="org.jeecg.modules.base.entity.original.GardsSampleData">
SELECT
SAMPLE_ID,
STATION_ID,
ACQUISITION_START,
GRADING
FROM
ORIGINAL.GARDS_SAMPLE_DATA
WHERE
STATION_CODE = #{ stationCode }
AND ACQUISITION_START BETWEEN TO_DATE(#{ startTime }, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{ endTime }, 'YYYY-MM-DD HH24:MI:SS')
ORDER BY
ACQUISITION_START
</select>
<select id="selectByStationIds" resultType="org.jeecg.entity.ThresholdMetric">
SELECT
a.STATION_ID as STATION_ID,
a.SAMPLE_ID as SAMPLE_ID,
b.NUCLIDENAME as NUCLIDE_NAME,
b.CONCENTRATION as CONCENTRATION
FROM ORIGINAL.GARDS_SAMPLE_DATA a
JOIN RNAUTO.GARDS_NUCL_IDED b
ON a.SAMPLE_ID = b.SAMPLE_ID
<where>
a.STATION_ID IN
<foreach item="stationId" collection="stationIds" open="(" close=")" separator=",">
'${stationId}'
</foreach>
AND a.ACQUISITION_START BETWEEN TO_DATE(#{ startTime }, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{ endTime }, 'YYYY-MM-DD HH24:MI:SS')
</where>
</select>
<select id="getRnAutoSampleGradeAnalysis" resultType="org.jeecg.entity.SampleLevelData">
SELECT
t1.SAMPLE_ID,
t1.COLLECT_STOP,
t1.STATION_ID,
t2.CATEGORY
FROM
ORIGINAL.GARDS_SAMPLE_DATA t1
LEFT JOIN RNAUTO.GARDS_ANALYSES t2
ON t1.SAMPLE_ID = t2.SAMPLE_ID
WHERE
t1.STATION_ID=#{station}
AND t1.SAMPLE_TYPE=#{sampleType}
AND t1.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<select id="getRnManSampleGradeAnalysis" resultType="org.jeecg.entity.SampleLevelData">
SELECT
t1.SAMPLE_ID,
t1.COLLECT_STOP,
t1.STATION_ID,
t2.CATEGORY
FROM
ORIGINAL.GARDS_SAMPLE_DATA t1
LEFT JOIN RNMAN.GARDS_ANALYSES t2
ON t1.SAMPLE_ID = t2.SAMPLE_ID
WHERE
t1.STATION_ID=#{station}
AND t1.SAMPLE_TYPE=#{sampleType}
AND t1.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!-- 数据源 RNAUTO-->
<!-- 获取样品的级别和阈值-->
<select id="getRnAutoSampleLevel" resultType="org.jeecg.entity.SampleLevelData">
select a.SAMPLE_ID,
a.COLLECT_STOP,
b.CATEGORY
from
ORIGINAL.GARDS_SAMPLE_DATA a,
RNAUTO.GARDS_ANALYSES b
WHERE a.SAMPLE_ID=b.SAMPLE_ID
AND a.STATION_ID=#{station}
AND a.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<select id="getRnManSampleLevel" resultType="org.jeecg.entity.SampleLevelData">
select a.SAMPLE_ID,
a.COLLECT_STOP,
b.CATEGORY
from
ORIGINAL.GARDS_SAMPLE_DATA a,
RNMAN.GARDS_ANALYSES b
WHERE a.SAMPLE_ID=b.SAMPLE_ID
AND a.STATION_ID=#{station}
AND a.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!-- 获取样品中元素的浓度活度、MDC信息-->
<select id="getRnautoPNuclideActConcIntvl" resultType="org.jeecg.entity.NuclideActConcIntvl">
SELECT
a.SAMPLE_ID,
a.COLLECT_STOP,
a.SAMPLE_TYPE,
a.STATION_ID,
a.STATUS,
b.NUCLIDENAME NUCLIDE_NAME,
b.CONCENTRATION AS conc,
b.MDC,
b.ACTIV_KEY_ERR AS concErr
FROM
ORIGINAL.GARDS_SAMPLE_DATA a
INNER JOIN
RNAUTO.GARDS_NUCL_IDED b
ON a.SAMPLE_ID = b.SAMPLE_ID
WHERE
a.SAMPLE_TYPE = #{sampleType}
AND a.STATION_ID=#{station}
AND b.NUCLIDENAME=#{nuclideName}
AND a.COLLECT_START BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!-- 获取样品类型=气体 元素的浓度活度、MDC信息-->
<select id="getRnautoNuclideActConcIntvl" resultType="org.jeecg.entity.NuclideActConcIntvl">
SELECT
a.SAMPLE_ID,
a.COLLECT_STOP,
a.SAMPLE_TYPE,
a.STATION_ID,
a.STATUS,
b.NUCLIDE_NAME,
b.CONC,
b.MDC,
b.CONC_ERR
FROM
ORIGINAL.GARDS_SAMPLE_DATA a
INNER JOIN
RNAUTO.GARDS_XE_RESULTS b
ON a.SAMPLE_ID = b.SAMPLE_ID
WHERE
a.SAMPLE_TYPE = '#{sampleType}'
AND a.STATION_ID=#{station}
AND b.NUCLIDENAME=#{nuclideName}
AND a.COLLECT_START BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!-- 数据源 RNMAN-->
<!-- 获取样品中元素的浓度活度、MDC信息-->
<select id="getRnmanPNuclideActConcIntvl" resultType="org.jeecg.entity.NuclideActConcIntvl">
SELECT
a.SAMPLE_ID,
a.COLLECT_STOP,
a.SAMPLE_TYPE,
a.STATION_ID,
a.STATUS,
b.NUCLIDENAME NUCLIDE_NAME,
b.CONCENTRATION AS conc,
b.MDC,
b.ACTIV_KEY_ERR AS concErr
FROM
ORIGINAL.GARDS_SAMPLE_DATA a
INNER JOIN
RNMAN.GARDS_NUCL_IDED b
ON a.SAMPLE_ID = b.SAMPLE_ID
WHERE
a.SAMPLE_TYPE = '#{sampleType}'
AND a.STATION_ID=#{station}
AND b.NUCLIDENAME=#{nuclideName}
AND a.COLLECT_START BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!-- 获取样品类型=气体 元素的浓度活度、MDC信息-->
<select id="getRnmanNuclideActConcIntvl" resultType="org.jeecg.entity.NuclideActConcIntvl">
SELECT
a.SAMPLE_ID,
a.COLLECT_STOP,
a.SAMPLE_TYPE,
a.STATION_ID,
a.STATUS,
b.NUCLIDE_NAME,
b.CONC,
b.MDC,
b.CONC_ERR
FROM
ORIGINAL.GARDS_SAMPLE_DATA a
INNER JOIN
RNMAN.GARDS_XE_RESULTS b
ON a.SAMPLE_ID = b.SAMPLE_ID
WHERE
a.SAMPLE_TYPE = '#{sampleType}'
AND a.STATION_ID=#{station}
AND b.NUCLIDENAME=#{nuclideName}
AND a.COLLECT_START BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!--region 样品统计分析-->
<!-- RnAuto 获取样品中识别到的核素集合-->
<select id="getRnAutoIdentifiedNuclides" resultType="org.jeecg.entity.NuclideActConcIntvl">
SELECT t1.SAMPLE_ID AS sampleId,
t1.COLLECT_STOP AS collectStop,
t1.SAMPLE_TYPE AS sampleType,
t1.STATION_ID AS stationId,
t1.STATUS AS status,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
t2.NUCLIDENAME
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.NUCLIDE_NAME
END AS NUCLIDE_NAME,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
TO_NUMBER(REGEXP_REPLACE(t2.CONCENTRATION, '[^0-9.Ee-]', ''))
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.CONC
END AS conc,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
TO_NUMBER(REGEXP_REPLACE(t2.MDC, '[^0-9.Ee-]', ''))
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.MDC
END AS mdc
FROM ORIGINAL.GARDS_SAMPLE_DATA t1
LEFT JOIN RNAUTO.GARDS_NUCL_IDED t2 ON t1.SAMPLE_TYPE = 'P'
AND t1.SAMPLE_ID = t2.SAMPLE_ID
LEFT JOIN RNAUTO.GARDS_XE_RESULTS t3 ON t1.SAMPLE_TYPE = 'B'
AND t1.SAMPLE_ID = t3.SAMPLE_ID
WHERE t1.STATION_ID = #{station}
AND t1.STATUS != 'F'
AND t1.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!-- RnAuto 核素等级时序分析-->
<select id="getRnAutoNuclideTimeSeriesAnalysis" resultType="org.jeecg.entity.SampleLevelData">
SELECT
A.SAMPLE_ID AS "sampleId",
A.COLLECT_STOP AS "collectStop",
B.CATEGORY AS "grading"
FROM
ORIGINAL.GARDS_SAMPLE_DATA A
INNER JOIN
RNAUTO.GARDS_ANALYSES B
ON A.SAMPLE_ID = B.SAMPLE_ID
WHERE
A.STATION_ID = #{station}
AND A.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!-- RnMan 获取样品中识别到的核素集合-->
<select id="getRnManIdentifiedNuclides" resultType="org.jeecg.entity.NuclideActConcIntvl">
SELECT
t1.SAMPLE_ID AS sampleId,
t1.COLLECT_STOP AS collectStop,
t1.SAMPLE_TYPE AS sampleType,
t1.STATION_ID AS stationId,
t1.STATUS AS status,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
t2.NUCLIDENAME
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.NUCLIDE_NAME
END AS NUCLIDE_NAME,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
TO_NUMBER(REGEXP_REPLACE(t2.CONCENTRATION, '[^0-9.Ee-]', ''))
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.CONC
END AS conc
FROM
ORIGINAL.GARDS_SAMPLE_DATA t1
LEFT JOIN RNMAN.GARDS_NUCL_IDED t2 ON t1.SAMPLE_TYPE = 'P'
AND t1.SAMPLE_ID = t2.SAMPLE_ID
LEFT JOIN RNMAN.GARDS_XE_RESULTS t3 ON t1.SAMPLE_TYPE = 'B'
AND t1.SAMPLE_ID = t3.SAMPLE_ID
WHERE
t1.STATION_ID = #{station}
AND t1.STATUS != 'F'
AND t1.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<!-- RnMan 核素等级时序分析-->
<select id="getRnManNuclideTimeSeriesAnalysis" resultType="org.jeecg.entity.SampleLevelData">
SELECT
A.SAMPLE_ID AS "sampleId",
A.COLLECT_STOP AS "collectStop",
B.CATEGORY AS "grading"
FROM
ORIGINAL.GARDS_SAMPLE_DATA A
INNER JOIN
RNMAN.GARDS_ANALYSES B
ON A.SAMPLE_ID = B.SAMPLE_ID
WHERE
A.STATION_ID = #{station}
AND A.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
</select>
<select id="selectByStationAndNuclide" resultType="org.jeecg.entity.GardsThresholdResultHis">
SELECT *
FROM ${schemaName}.GARDS_THRESHOLD_RESULT_HIS
WHERE STATION_ID = #{stationId}
AND NUCLIDENAME = #{nuclideName}
AND CALCULATION_TIME BETWEEN #{startTime} AND #{endTime}
ORDER BY CALCULATION_TIME DESC
</select>
<!-- 查询多个站点和多个核素 -->
<select id="selectByStationsAndNuclides" resultType="org.jeecg.entity.GardsThresholdResultHis">
SELECT * FROM ${schemaName}.GARDS_THRESHOLD_RESULT_HIS A
WHERE A.STATION_ID IN
<foreach collection="stationIds" item="stationId" open="(" separator="," close=")">
#{stationId}
</foreach>
AND A.NUCLIDENAME IN
<foreach collection="nuclideNames" item="nuclideName" open="(" separator="," close=")">
#{nuclideName}
</foreach>
AND CALCULATION_TIME BETWEEN #{startTime} AND #{endTime}
ORDER BY CALCULATION_TIME DESC
</select>
<!-- 查询多个站点 + 单个核素 -->
<select id="selectByStationsAndNuclide" resultType="org.jeecg.entity.GardsThresholdResultHis">
SELECT * FROM ${schemaName}.GARDS_THRESHOLD_RESULT_HIS A
WHERE A.STATION_ID IN
<foreach collection="stationIds" item="stationId" open="(" separator="," close=")">
#{stationId}
</foreach>
AND A.NUCLIDENAME = #{nuclideName}
AND CALCULATION_TIME BETWEEN #{startTime} AND #{endTime}
ORDER BY CALCULATION_TIME DESC
</select>
<!-- 查询单个站点 + 多个核素 -->
<select id="selectByStationAndNuclides" resultType="org.jeecg.entity.GardsThresholdResultHis">
SELECT * FROM ${schemaName}.GARDS_THRESHOLD_RESULT_HIS A
WHERE A.STATION_ID = #{stationId}
AND A.NUCLIDENAME IN
<foreach collection="nuclideNames" item="nuclideName" open="(" separator="," close=")">
#{nuclideName}
</foreach>
AND CALCULATION_TIME BETWEEN TO_DATE(#{ startTime }, 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE(#{ endTime }, 'YYYY-MM-DD HH24:MI:SS')
ORDER BY CALCULATION_TIME DESC
</select>
<select id="selectByCondition" resultType="org.jeecg.entity.GardsThresholdResultHis">
SELECT * FROM ${schemaName}.GARDS_THRESHOLD_RESULT_HIS
<where>
<if test="stationIds != null and stationIds.size() > 0">
AND STATION_ID IN
<foreach collection="stationIds" item="stationId" open="(" separator="," close=")">
#{stationId}
</foreach>
</if>
<if test="nuclideNames != null and nuclideNames.size() > 0">
AND NUCLIDENAME IN
<foreach collection="nuclideNames" item="nuclideName" open="(" separator="," close=")">
#{nuclideName}
</foreach>
</if>
<if test="startTime != null and startTime != ''">
AND CALCULATION_TIME &gt; TO_DATE(#{ startTime }, 'YYYY-MM-DD HH24:MI:SS')
</if>
<if test="endTime != null and endTime != ''">
AND CALCULATION_TIME &lt; TO_DATE(#{ endTime }, 'YYYY-MM-DD HH24:MI:SS')
</if>
</where>
ORDER BY CALCULATION_TIME DESC
</select>
<!-- 核素活度浓度对比分析-->
<select id="getRnAutoAnalyzeNuclideActivityConc" resultType="org.jeecg.entity.NuclideActConcIntvl">
SELECT
t1.SAMPLE_ID AS sampleId,
t1.COLLECT_STOP AS collectStop,
t1.SAMPLE_TYPE AS sampleType,
t1.STATION_ID AS stationId,
t1.STATUS AS status,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
t2.NUCLIDENAME
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.NUCLIDE_NAME
END AS NUCLIDE_NAME,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
TO_NUMBER(REGEXP_REPLACE(t2.CONCENTRATION, '[^0-9.Ee-]', ''))
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.CONC
END AS conc
FROM
ORIGINAL.GARDS_SAMPLE_DATA t1
LEFT JOIN RNAUTO.GARDS_NUCL_IDED t2 ON t1.SAMPLE_TYPE = 'P'
AND t1.SAMPLE_ID = t2.SAMPLE_ID
LEFT JOIN RNAUTO.GARDS_XE_RESULTS t3 ON t1.SAMPLE_TYPE = 'B'
AND t1.SAMPLE_ID = t3.SAMPLE_ID
<where>
t1.STATION_ID IN
<foreach item="stationId" collection="stationIds" open="(" close=")" separator=",">
'${stationId}'
</foreach>
AND t1.SAMPLE_TYPE=#{sampleType}
AND t1.COLLECT_STOP BETWEEN TO_DATE(#{ startTime }, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{ endTime }, 'YYYY-MM-DD HH24:MI:SS')
</where>
</select>
<select id="getRnManAnalyzeNuclideActivityConc" resultType="org.jeecg.entity.NuclideActConcIntvl">
SELECT
t1.SAMPLE_ID AS sampleId,
t1.COLLECT_STOP AS collectStop,
t1.SAMPLE_TYPE AS sampleType,
t1.STATION_ID AS stationId,
t1.STATUS AS status,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
t2.NUCLIDENAME
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.NUCLIDE_NAME
END AS NUCLIDE_NAME,
CASE
WHEN t1.SAMPLE_TYPE = 'P' THEN
TO_NUMBER(REGEXP_REPLACE(t2.CONCENTRATION, '[^0-9.Ee-]', ''))
WHEN t1.SAMPLE_TYPE = 'B' THEN
t3.CONC
END AS conc
FROM
ORIGINAL.GARDS_SAMPLE_DATA t1
LEFT JOIN RNMAN.GARDS_NUCL_IDED t2 ON t1.SAMPLE_TYPE = 'P'
AND t1.SAMPLE_ID = t2.SAMPLE_ID
LEFT JOIN RNMAN.GARDS_XE_RESULTS t3 ON t1.SAMPLE_TYPE = 'B'
AND t1.SAMPLE_ID = t3.SAMPLE_ID
<where>
t1.STATION_ID IN
<foreach item="stationId" collection="stationIds" open="(" close=")" separator=",">
'${stationId}'
</foreach>
AND t1.SAMPLE_TYPE=#{sampleType}
AND t1.COLLECT_STOP BETWEEN TO_DATE(#{ startTime }, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{ endTime }, 'YYYY-MM-DD HH24:MI:SS')
</where>
</select>
<!--样品监测结果-->
<!-- 先查出台站信息-->
<!-- 再根据台站级别信息-->
<select id="getRnAutoSampleResult" resultType="org.jeecg.entity.StationInfoData">
SELECT
t1.SAMPLE_ID,
t1.COLLECT_STOP,
t1.STATION_ID,
c1.STATION_CODE,
c1.COUNTRY_CODE,
c1.TYPE,
c1.LON,
c1.LAT,
c1.STATUS,
c1.DESCRIPTION,
t2.CATEGORY
FROM
ORIGINAL.GARDS_SAMPLE_DATA t1
LEFT JOIN RNAUTO.GARDS_ANALYSES t2
ON t1.SAMPLE_ID = t2.SAMPLE_ID
LEFT JOIN CONFIGURATION.GARDS_STATIONS c1
ON t1.STATION_ID=c1.STATION_ID
WHERE
t1.SAMPLE_TYPE=#{sampleType}
AND t1.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
ORDER BY
t1.COLLECT_STOP ASC
</select>
<select id="getRnManSampleResult" resultType="org.jeecg.entity.StationInfoData">
SELECT
t1.SAMPLE_ID,
t1.COLLECT_STOP,
t1.STATION_ID,
c1.STATION_CODE,
c1.COUNTRY_CODE,
c1.TYPE,
c1.LON,
c1.LAT,
c1.STATUS,
c1.DESCRIPTION,
t2.CATEGORY
FROM
ORIGINAL.GARDS_SAMPLE_DATA t1
LEFT JOIN RNMAN.GARDS_ANALYSES t2
ON t1.SAMPLE_ID = t2.SAMPLE_ID
LEFT JOIN CONFIGURATION.GARDS_STATIONS c1
ON t1.STATION_ID=c1.STATION_ID
WHERE
t1.SAMPLE_TYPE=#{sampleType}
AND t1.COLLECT_STOP BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD hh24:mi:ss')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD hh24:mi:ss')
ORDER BY
t1.COLLECT_STOP ASC
</select>
</mapper>

View File

@ -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<GardsSampleData> {
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);
}

View File

@ -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<GardsSampleStatAnalysisMapper, GardsSampleData> implements ISampleStatAnalysisService {
public Result getSampleMonitorResult(String sampleType, Integer dataSource, Date startDate, Date endDate) {
Result result = new Result();
//声明返回用的结果map
Map<String, Object> resultMap = new HashMap<>();
List<StationInfoData> 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<String, List<StationInfoData>> 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<String, Object> resultMap = new HashMap<>();
List<NuclideActConcIntvl> nuclideActConcIntvlList = new ArrayList<>();
List<SampleLevelData> sampleLevelDataList = new ArrayList<>();
List<GardsThresholdResultHis> 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<String, List<NuclideActConcIntvl>> groupedByNuclideName = nuclideActConcIntvlList.stream()
.filter(p->p.getNuclideName()!=null)
.collect(Collectors.groupingBy(NuclideActConcIntvl::getNuclideName));
//查询级别 getSample
List<String> 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<String, Object> resultMap = new HashMap<>();
List<SampleLevelData> 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<String, Object> resultMap = new HashMap<>();
List<NuclideActConcIntvl> 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<Double> data = DistributionAnalysisToolkit.convertConcToDoubleList(nuclideActConcIntvls);
// 设置区间参数
double start = 0; // 区间起始值
double step = 200; // 区间步长宽度
// 1. 区间统计
List<DistributionAnalysisToolkit.IntervalStat> stats = DistributionAnalysisToolkit.calculateIntervalStats(data, start, step);
// 3. 累积分布函数
List<DistributionAnalysisToolkit.CDFPoint> cdfPoints = DistributionAnalysisToolkit.calculateCDF(data);
// 4. 核密度估计
List<DistributionAnalysisToolkit.KDEPoint> kdePoints = DistributionAnalysisToolkit.autoKDE(data, DistributionAnalysisToolkit.GAUSSIAN_KERNEL);
//获取所有浓度的累积
List<Double> 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<String, Object> 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<SampleLevelData> sampleDatas = new ArrayList<>();
//核素的阈值
List<GardsThresholdResultHis> thresholdResultHisList = new ArrayList<>();
List<NuclideActConcIntvl> 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<String, Object> resultMap = new HashMap<>();
List<NuclideActConcIntvl> 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;
}
}

View File

@ -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<Double> values;
public IntervalStat(String interval, int count, List<Double> values) {
this.interval = interval;
this.count = count;
this.values = values;
}
public String getInterval() { return interval; }
public int getCount() { return count; }
public List<Double> 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<IntervalStat> calculateIntervalStats(List<Double> 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<String, List<Double>> 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<IntervalStat> stats = new ArrayList<>();
for (Map.Entry<String, List<Double>> 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<Double> data) {
if (data == null || data.isEmpty()) {
throw new IllegalArgumentException("数据不能为空");
}
// 排序数据
List<Double> 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<CDFPoint> calculateCDF(List<Double> data) {
if (data == null || data.isEmpty()) {
throw new IllegalArgumentException("数据不能为空");
}
// 排序数据
List<Double> sortedData = new ArrayList<>(data);
Collections.sort(sortedData);
// 计算累积分布
List<CDFPoint> 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<Double> 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<Double> 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<KDEPoint> kernelDensityEstimate(
List<Double> 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<KDEPoint> 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<KDEPoint> autoKDE(List<Double> data, KernelFunction kernel) {
double bandwidth = calculateBandwidthSilverman(data);
return kernelDensityEstimate(data, kernel, bandwidth);
}
//获取浓度值集合
public static List<Double> convertConcToDoubleList(List<NuclideActConcIntvl> nuclideList) {
return nuclideList.stream() // 创建流
.map(NuclideActConcIntvl::getConc) // 提取conc值
.collect(Collectors.toList()); // 收集为List<Double>
}
//累积和
public static List<Double> cumulativeSum(List<Double> data) {
List<Double> result = new ArrayList<>();
double sum = 0.0;
for (double value : data) {
sum += value;
result.add(sum);
}
return result;
}
}