fix: 核素分析规则 增加核素识别报警,求平均值的周期和系数都整合到规则中

This commit is contained in:
xiaoguangbin 2025-01-08 16:34:33 +08:00
parent 5317fe2b56
commit accc1d798e
11 changed files with 267 additions and 123 deletions

View File

@ -59,4 +59,10 @@ public class AlarmAnalysisRuleInfo implements Serializable {
private Integer xe133Flag; private Integer xe133Flag;
private Integer xe135Flag; private Integer xe135Flag;
private Integer days;
private String identifyNuclides;
private List<String> identifyNuclidesChecked;
} }

View File

@ -9,6 +9,7 @@ import org.jeecg.modules.base.enums.SourceType;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
import java.util.Set;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@ -48,4 +49,6 @@ public class Info implements Serializable{
private String groupId; private String groupId;
private String conditions; private String conditions;
private Set<String> identifyNuclideSet;
} }

View File

@ -1,19 +1,22 @@
package org.jeecg.modules.base.entity.postgre; package org.jeecg.modules.base.entity.postgre;
import com.baomidou.mybatisplus.annotation.FieldStrategy; import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.jeecg.common.system.base.entity.JeecgEntity; import org.jeecg.common.system.base.entity.JeecgEntity;
import java.math.BigDecimal;
@Data @Data
@TableName("alarm_analysis_rule") @TableName("alarm_analysis_rule")
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Accessors(chain = true) @Accessors(chain = true)
public class AlarmAnalysisRule extends JeecgEntity { public class AlarmAnalysisRule extends JeecgEntity {
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/** 规则名称 */ /** 规则名称 */
private String name; private String name;
@ -42,7 +45,7 @@ public class AlarmAnalysisRule extends JeecgEntity {
private String sampleType; private String sampleType;
private Integer coefficient; private BigDecimal coefficient;
@TableField(updateStrategy = FieldStrategy.IGNORED) @TableField(updateStrategy = FieldStrategy.IGNORED)
private String colTime; private String colTime;
@ -82,6 +85,10 @@ public class AlarmAnalysisRule extends JeecgEntity {
@TableField(value = "xe135_flag", updateStrategy = FieldStrategy.IGNORED) @TableField(value = "xe135_flag", updateStrategy = FieldStrategy.IGNORED)
private Integer xe135Flag; private Integer xe135Flag;
private Integer days;
private String identifyNuclides;
/** 备注 */ /** 备注 */
private String remark; private String remark;
} }

View File

@ -7,7 +7,22 @@ import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum Condition { public enum Condition {
FIRST_FOUND("1"), ABOVE_AVERAGE("2"), MEANWHILE("3"); /**
* 首次发现核素
*/
FIRST_FOUND("1"),
/**
* 核素conc超过平均值
*/
ABOVE_AVERAGE("2"),
/**
* 同时识别到多个核素
*/
MEANWHILE("3"),
/**
* 识别到某个核素
*/
IDENTIFY_NUCLIDES("4");
private final String value; private final String value;

View File

@ -3,6 +3,7 @@
<mapper namespace="org.jeecg.modules.mapper.GardsNuclIdedAutoMapper"> <mapper namespace="org.jeecg.modules.mapper.GardsNuclIdedAutoMapper">
<select id="getConc" resultType="org.jeecg.modules.base.dto.ConcDto"> <select id="getConc" resultType="org.jeecg.modules.base.dto.ConcDto">
SELECT SELECT
DISTINCT samp.SAMPLE_ID,
nucl.NUCLIDENAME, nucl.NUCLIDENAME,
nucl.CONCENTRATION AS CONC, nucl.CONCENTRATION AS CONC,
ana.ANALYSISBEGIN ana.ANALYSISBEGIN
@ -16,6 +17,7 @@
AND to_date(#{endDate},'yyyy-mm-dd hh24:mi:ss') AND to_date(#{endDate},'yyyy-mm-dd hh24:mi:ss')
AND samp.DATA_TYPE = 'S' AND samp.STATUS IN ('P', 'R') AND samp.DATA_TYPE = 'S' AND samp.STATUS IN ('P', 'R')
AND samp.STATION_ID = #{stationId} AND samp.STATION_ID = #{stationId}
AND samp.SPECTRAL_QUALIFIE = 'FULL'
<if test="nuclideName != null and nuclideName.size() > 0"> <if test="nuclideName != null and nuclideName.size() > 0">
AND nucl.NUCLIDENAME IN AND nucl.NUCLIDENAME IN
<foreach collection="nuclideName" open="(" close=")" index="index" item="item" separator=","> <foreach collection="nuclideName" open="(" close=")" index="index" item="item" separator=",">

View File

@ -3,24 +3,51 @@
<mapper namespace="org.jeecg.modules.mapper.GardsNuclIdedManMapper"> <mapper namespace="org.jeecg.modules.mapper.GardsNuclIdedManMapper">
<select id="getConc" resultType="org.jeecg.modules.base.dto.ConcDto"> <select id="getConc" resultType="org.jeecg.modules.base.dto.ConcDto">
SELECT SELECT
DISTINCT samp.SAMPLE_ID,
nucl.NUCLIDENAME, nucl.NUCLIDENAME,
nucl.CONCENTRATION AS CONC, nucl.CONCENTRATION AS CONC,
ana.ANALYSISBEGIN ana.ANALYSISBEGIN
FROM FROM
RNMAN.GARDS_NUCL_IDED nucl RNMAN.GARDS_NUCL_IDED nucl
INNER JOIN RNMAN.GARDS_ANALYSES ana ON ana.IDANALYSIS = nucl.IDANALYSIS INNER JOIN RNMAN.GARDS_ANALYSES ana ON ana.IDANALYSIS = nucl.IDANALYSIS
INNER JOIN ORIGINAL.GARDS_SAMPLE_DATA samp ON samp.SAMPLE_ID = nucl.SAMPLE_ID INNER JOIN ORIGINAL.GARDS_SAMPLE_DATA samp ON samp.SAMPLE_ID = nucl.SAMPLE_ID
INNER JOIN RNMAN.GARDS_QC_CHECK qc ON samp.SAMPLE_ID = qc.SAMPLE_ID
<where> <where>
ana.ANALYSISBEGIN BETWEEN to_date(#{startDate},'yyyy-mm-dd hh24:mi:ss') ana.ANALYSISBEGIN BETWEEN to_date(#{startDate},'yyyy-mm-dd hh24:mi:ss')
AND to_date(#{endDate},'yyyy-mm-dd hh24:mi:ss') AND to_date(#{endDate},'yyyy-mm-dd hh24:mi:ss')
AND samp.DATA_TYPE = 'S' AND samp.STATUS IN ('P', 'R') AND samp.DATA_TYPE = 'S' AND samp.STATUS IN ('P', 'R')
AND samp.STATION_ID = #{stationId} AND samp.STATION_ID = #{stationId}
AND samp.SPECTRAL_QUALIFIE = 'FULL'
<if test="nuclideName != null and nuclideName.size() > 0"> <if test="nuclideName != null and nuclideName.size() > 0">
AND nucl.NUCLIDENAME IN AND nucl.NUCLIDENAME IN
<foreach collection="nuclideName" open="(" close=")" index="index" item="item" separator=","> <foreach collection="nuclideName" open="(" close=")" index="index" item="item" separator=",">
#{item} #{item}
</foreach> </foreach>
</if> </if>
<if test="colTime != null and colTime.size() > 0">
AND (qc.qc_name = 'col_time' and qc.qc_value between #{colTime[0]} and #{colTime[1]} )
</if>
<if test="acqTime != null and acqTime.size() > 0">
AND (qc.qc_name = 'acq_time' and qc.qc_value between #{acqTime[0]} and #{acqTime[1]} )
</if>
<if test="airFlow != null">
AND (qc.qc_name = 'air_flow' and qc.qc_value &lt; #{airFlow} )
</if>
<if test="decayTime != nul">
AND (qc.qc_name = 'decay_time' and qc.qc_value &lt; #{decayTime} )
</if>
<if test="sampVol != null">
AND (qc.qc_name = 'samp_vol' and qc.qc_value &lt; #{sampVol} )
</if>
<if test="be7FWHM != null">
AND (qc.qc_name = 'Be7-FWHM' and qc.qc_value &lt; #{be7FWHM} )
</if>
<if test="ba140MDC != null">
AND (qc.qc_name = 'Ba140-MDC' and qc.qc_value &lt; #{ba140MDC} )
</if>
<if test="xe133MDC != null">
AND (qc.qc_name = 'Xe133-MDC' and qc.qc_value &lt; #{xe133MDC} )
</if>
</where> </where>
</select> </select>
<select id="sampNucl" resultType="org.jeecg.modules.base.dto.SampNucl"> <select id="sampNucl" resultType="org.jeecg.modules.base.dto.SampNucl">

View File

@ -3,6 +3,7 @@
<mapper namespace="org.jeecg.modules.mapper.GardsXeResultsAutoMapper"> <mapper namespace="org.jeecg.modules.mapper.GardsXeResultsAutoMapper">
<select id="getConc" resultType="org.jeecg.modules.base.dto.ConcDtoXe"> <select id="getConc" resultType="org.jeecg.modules.base.dto.ConcDtoXe">
SELECT SELECT
DISTINCT samp.SAMPLE_ID,
xe.NUCLIDE_NAME, xe.NUCLIDE_NAME,
xe.CONC, xe.CONC,
ana.ANALYSISBEGIN ana.ANALYSISBEGIN
@ -16,6 +17,7 @@
AND to_date(#{endDate},'yyyy-mm-dd hh24:mi:ss') AND to_date(#{endDate},'yyyy-mm-dd hh24:mi:ss')
AND samp.DATA_TYPE = 'S' AND samp.STATUS IN ('P', 'R') AND samp.DATA_TYPE = 'S' AND samp.STATUS IN ('P', 'R')
AND samp.STATION_ID = #{stationId} AND samp.STATION_ID = #{stationId}
AND samp.SPECTRAL_QUALIFIE = 'FULL'
<if test="nuclideName != null and nuclideName.size() > 0"> <if test="nuclideName != null and nuclideName.size() > 0">
AND xe.NUCLIDE_NAME IN AND xe.NUCLIDE_NAME IN
<foreach collection="nuclideName" open="(" close=")" index="index" item="item" separator=","> <foreach collection="nuclideName" open="(" close=")" index="index" item="item" separator=",">
@ -34,6 +36,18 @@
<if test="Xe133MDC != null and Xe133MDC.size() > 0"> <if test="Xe133MDC != null and Xe133MDC.size() > 0">
AND (xe.NUCLIDE_NAME = 'Xe133m' AND MDC between #{Xe133MDC[0]} AND #{Xe133MDC[1]} ) AND (xe.NUCLIDE_NAME = 'Xe133m' AND MDC between #{Xe133MDC[0]} AND #{Xe133MDC[1]} )
</if> </if>
<if test="Xe133mFlag != null">
AND (xe.NUCLIDE_NAME = 'Xe133m' AND xe.NID_FLAG = 1 )
</if>
<if test="Xe133Flag != null">
AND (xe.NUCLIDE_NAME = 'Xe133' AND xe.NID_FLAG = 1 )
</if>
<if test="Xe131mFlag != null">
AND (xe.NUCLIDE_NAME = 'Xe131m' AND xe.NID_FLAG = 1 )
</if>
<if test="Xe135Flag != null ">
AND (xe.NUCLIDE_NAME = 'Xe135' AND xe.NID_FLAG = 1 )
</if>
</where> </where>
</select> </select>
<select id="sampNucl" resultType="org.jeecg.modules.base.dto.SampNucl"> <select id="sampNucl" resultType="org.jeecg.modules.base.dto.SampNucl">

View File

@ -3,6 +3,7 @@
<mapper namespace="org.jeecg.modules.mapper.GardsXeResultsManMapper"> <mapper namespace="org.jeecg.modules.mapper.GardsXeResultsManMapper">
<select id="getConc" resultType="org.jeecg.modules.base.dto.ConcDtoXe"> <select id="getConc" resultType="org.jeecg.modules.base.dto.ConcDtoXe">
SELECT SELECT
DISTINCT samp.SAMPLE_ID,
xe.NUCLIDE_NAME, xe.NUCLIDE_NAME,
xe.CONC, xe.CONC,
ana.ANALYSISBEGIN ana.ANALYSISBEGIN
@ -10,17 +11,31 @@
RNMAN.GARDS_XE_RESULTS xe RNMAN.GARDS_XE_RESULTS xe
INNER JOIN RNMAN.GARDS_ANALYSES ana ON ana.IDANALYSIS = xe.IDANALYSIS INNER JOIN RNMAN.GARDS_ANALYSES ana ON ana.IDANALYSIS = xe.IDANALYSIS
INNER JOIN ORIGINAL.GARDS_SAMPLE_DATA samp ON samp.SAMPLE_ID = xe.SAMPLE_ID INNER JOIN ORIGINAL.GARDS_SAMPLE_DATA samp ON samp.SAMPLE_ID = xe.SAMPLE_ID
INNER JOIN ORIGINAL.GARDS_SAMPLE_AUX aux ON samp.SAMPLE_ID = aux.SAMPLE_ID
<where> <where>
ana.ANALYSISBEGIN BETWEEN to_date(#{startDate},'yyyy-mm-dd hh24:mi:ss') ana.ANALYSISBEGIN BETWEEN to_date(#{startDate},'yyyy-mm-dd hh24:mi:ss')
AND to_date(#{endDate},'yyyy-mm-dd hh24:mi:ss') AND to_date(#{endDate},'yyyy-mm-dd hh24:mi:ss')
AND samp.DATA_TYPE = 'S' AND samp.STATUS IN ('P', 'R') AND samp.DATA_TYPE = 'S' AND samp.STATUS IN ('P', 'R')
AND samp.STATION_ID = #{stationId} AND samp.STATION_ID = #{stationId}
AND samp.SPECTRAL_QUALIFIE = 'FULL'
<if test="nuclideName != null and nuclideName.size() > 0"> <if test="nuclideName != null and nuclideName.size() > 0">
AND xe.NUCLIDE_NAME IN AND xe.NUCLIDE_NAME IN
<foreach collection="nuclideName" open="(" close=")" index="index" item="item" separator=","> <foreach collection="nuclideName" open="(" close=")" index="index" item="item" separator=",">
#{item} #{item}
</foreach> </foreach>
</if> </if>
<if test="colTime != null and colTime.size() > 0">
and ((TO_NUMBER(samp.COLLECT_STOP - samp.COLLECT_START) * 24) between #{colTime[0]} and #{colTime[1]} )
</if>
<if test="acqTime != null and acqTime.size() > 0">
and (samp.ACQUISITION_LIVE_SEC / 3600 between #{colTime[0]} and #{colTime[1]} )
</if>
<if test="XeVol != null">
AND (aux.XE_VOLUME &gt; #{XeVol} )
</if>
<if test="Xe133MDC != null and Xe133MDC.size() > 0">
AND (xe.NUCLIDE_NAME = 'Xe133m' AND MDC between #{Xe133MDC[0]} AND #{Xe133MDC[1]} )
</if>
</where> </where>
</select> </select>
<select id="sampNucl" resultType="org.jeecg.modules.base.dto.SampNucl"> <select id="sampNucl" resultType="org.jeecg.modules.base.dto.SampNucl">

View File

@ -107,6 +107,7 @@ public class AnalysisConsumer implements StreamListener<String, ObjectRecord<Str
if (StrUtil.isBlank(stationId)) return; if (StrUtil.isBlank(stationId)) return;
if (StrUtil.isBlank(sampleId)) return; if (StrUtil.isBlank(sampleId)) return;
if (MapUtil.isEmpty(nuclides)) return; if (MapUtil.isEmpty(nuclides)) return;
List<AlarmAnalysisRule> rules = ruleService.allAnalysisRule(); List<AlarmAnalysisRule> rules = ruleService.allAnalysisRule();
for (AlarmAnalysisRule rule : rules) { for (AlarmAnalysisRule rule : rules) {
// 当前规则是否有报警条件 // 当前规则是否有报警条件
@ -130,16 +131,24 @@ public class AnalysisConsumer implements StreamListener<String, ObjectRecord<Str
if (StrUtil.isBlank(nuclidesStr)) continue; if (StrUtil.isBlank(nuclidesStr)) continue;
Set<String> names = nuclides.keySet(); Set<String> names = nuclides.keySet();
List<String> follow = ListUtil.toList(nuclidesStr.split(COMMA)); List<String> follow = ListUtil.toList(nuclidesStr.split(COMMA));
// 因数据库 Xe核素名称 M大小写不统一先统一大小写再进行比较
Collection<String> followLower = follow.stream().map(String::toLowerCase).collect(Collectors.toList());
Collection<String> namesLower = names.stream().map(String::toLowerCase).collect(Collectors.toList());
// 推送过来的核素集合与所关注核素集合取交集 // 推送过来的核素集合与所关注核素集合取交集
Collection<String> cross = CollectionUtil.intersection(names, follow); Collection<String> cross = CollectionUtil.intersection(namesLower, followLower);
Collection<String> crossNew = cross.stream().map(f->f.replace("x", "X")).collect(Collectors.toList());
if (CollUtil.isEmpty(cross)) continue; if (CollUtil.isEmpty(cross)) continue;
Map<String, String> nuclidesCross = nuclides.entrySet().stream() Map<String, String> nuclidesCross = nuclides.entrySet().stream()
.filter(entry -> cross.contains(entry.getKey())) .filter(entry -> crossNew.contains(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
// 开始对交集中的核素进行条件判断 // 开始对交集中的核素进行条件判断
info.setRuleId(rule.getId()); info.setRuleId(rule.getId());
info.setGroupId(rule.getContactGroup()); info.setGroupId(rule.getContactGroup());
info.setConditions(rule.getConditions()); info.setConditions(rule.getConditions());
String[] inSplit = rule.getIdentifyNuclides().split(",");
if (inSplit.length > 1) {
info.setIdentifyNuclideSet(Arrays.stream(inSplit).map(f->f.replace("M", "m")).collect(Collectors.toSet()));
}
judge(info, nuclidesCross); judge(info, nuclidesCross);
} }
} }
@ -152,6 +161,7 @@ public class AnalysisConsumer implements StreamListener<String, ObjectRecord<Str
String stationId = info.getStationId(); String stationId = info.getStationId();
String sampleId = info.getSampleId(); String sampleId = info.getSampleId();
String sampleName = info.getSampleName(); String sampleName = info.getSampleName();
Set<String> identifyNuclideSet = info.getIdentifyNuclideSet();
// 获取谱文件采样日期 如果为null 则默认为LocalDate.now() // 获取谱文件采样日期 如果为null 则默认为LocalDate.now()
LocalDate collDate = ObjectUtil.isNull(info.getCollectionDate()) ? LocalDate.now() : LocalDate collDate = ObjectUtil.isNull(info.getCollectionDate()) ? LocalDate.now() :
info.getCollectionDate().toLocalDate(); info.getCollectionDate().toLocalDate();
@ -160,20 +170,27 @@ public class AnalysisConsumer implements StreamListener<String, ObjectRecord<Str
List<String> firstDetected = new ArrayList<>(); // 首次发现 List<String> firstDetected = new ArrayList<>(); // 首次发现
List<NuclideInfo> moreThanAvg = new ArrayList<>(); // 超浓度均值 List<NuclideInfo> moreThanAvg = new ArrayList<>(); // 超浓度均值
List<String> meanWhile = new ArrayList<>(); // 同时出现两种及以上核素 List<String> meanWhile = new ArrayList<>(); // 同时出现两种及以上核素
List<String> identifyNuclideResult = new ArrayList<>();
for (String con : conditions) { for (String con : conditions) {
Condition condition = Condition.valueOf1(con); Condition condition = Condition.valueOf1(con);
if (ObjectUtil.isNull(condition)) continue; if (ObjectUtil.isNull(condition)) continue;
switch (condition){ switch (condition){
case FIRST_FOUND: // 首次发现该元素 case FIRST_FOUND: // 首次发现该元素
firstDetected = firstDetected(betaOrGamma, datasource, stationId, sampleId, nuclideNames); firstDetected = this.firstDetected(betaOrGamma, datasource, stationId, sampleId, nuclideNames);
break; break;
case ABOVE_AVERAGE: // 元素浓度高于均值 case ABOVE_AVERAGE: // 元素浓度高于均值
moreThanAvg = moreThanAvg(datasource, stationId, collDate, nuclidesCross); moreThanAvg = this.moreThanAvg(datasource, stationId, collDate, nuclidesCross);
break; break;
case MEANWHILE: // 同时出现两种及以上核素 case MEANWHILE: // 同时出现两种及以上核素
meanWhile = meanWhile(betaOrGamma, datasource, sampleId, nuclideNames); for (String nuclideName : nuclideNames) {
nuclideNames.add(nuclideName.replace("m","M"));
}
meanWhile = this.meanWhile(betaOrGamma, datasource, sampleId, nuclideNames);
if (meanWhile.size() < 2) meanWhile = ListUtil.empty(); if (meanWhile.size() < 2) meanWhile = ListUtil.empty();
break; break;
case IDENTIFY_NUCLIDES: // 识别到某个核素
identifyNuclideResult = this.meanWhile(betaOrGamma, datasource, sampleId, identifyNuclideSet);
break;
default: default:
break; break;
} }
@ -190,6 +207,8 @@ public class AnalysisConsumer implements StreamListener<String, ObjectRecord<Str
} }
if (CollUtil.isNotEmpty(meanWhile)) if (CollUtil.isNotEmpty(meanWhile))
dataTool.put("meanwhile", CollUtil.join(meanWhile, StrUtil.COMMA + StrUtil.SPACE)); dataTool.put("meanwhile", CollUtil.join(meanWhile, StrUtil.COMMA + StrUtil.SPACE));
if (CollUtil.isNotEmpty(identifyNuclideResult))
dataTool.put("identifyNuclide", CollUtil.join(identifyNuclideResult, StrUtil.COMMA + StrUtil.SPACE));
// 如果报警数据为空 则不需要发送报警信息和生成报警日志 // 如果报警数据为空 则不需要发送报警信息和生成报警日志
if (MapUtil.isEmpty(dataTool.get())) return; if (MapUtil.isEmpty(dataTool.get())) return;
// 产生报警信息的Sample信息 // 产生报警信息的Sample信息

View File

@ -135,6 +135,9 @@ public class AlarmAnalysisRuleServiceImpl extends ServiceImpl<AlarmAnalysisRuleM
@Override @Override
public Result add(AlarmAnalysisRule alarmAnalysisRule) { public Result add(AlarmAnalysisRule alarmAnalysisRule) {
String name = alarmAnalysisRule.getName(); String name = alarmAnalysisRule.getName();
if (null != alarmAnalysisRule.getIdentifyNuclides()) {
alarmAnalysisRule.setConditions(alarmAnalysisRule.getConditions() + ",4");
}
if (ObjectUtil.isNotNull(getByName(name))) if (ObjectUtil.isNotNull(getByName(name)))
return Result.error("Rule Name" + Prompt.NOT_REPEAT); return Result.error("Rule Name" + Prompt.NOT_REPEAT);
boolean success = save(alarmAnalysisRule); boolean success = save(alarmAnalysisRule);
@ -150,6 +153,11 @@ public class AlarmAnalysisRuleServiceImpl extends ServiceImpl<AlarmAnalysisRuleM
String id = alarmAnalysisRule.getId(); String id = alarmAnalysisRule.getId();
String name = alarmAnalysisRule.getName(); String name = alarmAnalysisRule.getName();
String original = getById(id).getName(); String original = getById(id).getName();
if (null != alarmAnalysisRule.getIdentifyNuclides()) {
alarmAnalysisRule.setConditions(alarmAnalysisRule.getConditions() + ",4");
} else {
alarmAnalysisRule.setConditions(alarmAnalysisRule.getConditions().replace("4", ""));
}
if (!StrUtil.equalsIgnoreCase(name,original)){ if (!StrUtil.equalsIgnoreCase(name,original)){
if (ObjectUtil.isNotNull(getByName(name))) if (ObjectUtil.isNotNull(getByName(name)))
return Result.error("Rule Name" + Prompt.NOT_REPEAT); return Result.error("Rule Name" + Prompt.NOT_REPEAT);
@ -201,6 +209,12 @@ public class AlarmAnalysisRuleServiceImpl extends ServiceImpl<AlarmAnalysisRuleM
.toList(analysisRule.getXe133MDC().split(comma)); .toList(analysisRule.getXe133MDC().split(comma));
analysisRuleInfo.setColTime(xe133MDC); analysisRuleInfo.setColTime(xe133MDC);
} }
if (null != analysisRule.getIdentifyNuclides()) {
List<String> inList = ListUtil
.toList(analysisRule.getIdentifyNuclides().split(comma));
analysisRuleInfo.setIdentifyNuclidesChecked(inList);
}
return Result.OK(analysisRuleInfo); return Result.OK(analysisRuleInfo);
} }

View File

@ -2,6 +2,7 @@ package org.jeecg.modules.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
@ -75,44 +76,32 @@ public class CalculateConcServiceImpl implements CalculateConcService {
String comma = SymbolConstant.COMMA; String comma = SymbolConstant.COMMA;
// 获取所有生效的报警规则 // 获取所有生效的报警规则
List<AlarmAnalysisRule> analysisRules = analysisRuleService.allAnalysisRule(); List<AlarmAnalysisRule> analysisRules = analysisRuleService.allAnalysisRule();
List<AlarmAnalysisNuclideAvg> autoAvgs = new ArrayList<>(); // Auto
Map<String,Object> params = new HashMap<>(); List<AlarmAnalysisNuclideAvg> manAvgs = new ArrayList<>(); // Man
// 初始化台站类型
init();
// 对所有报警规则的关注台站和关注核素进行统计 // 对所有报警规则的关注台站和关注核素进行统计
Map<String, Set<String>> nuclideMap = new HashMap<>(); // key:台站code value:核素列表 Map<String, Set<String>> nuclideMap = new HashMap<>(); // key:台站code value:核素列表
for (AlarmAnalysisRule analysisRule : analysisRules) { for (AlarmAnalysisRule analysisRule : analysisRules) {
Map<String,Object> params = new HashMap<>();
BigDecimal coefficient = analysisRule.getCoefficient();
// 获取平均值计算的日期区间系数
Integer days = analysisRule.getDays();
LocalDate dayAgo = LocalDate.now().minusDays(1);
LocalDate daysAgo = dayAgo.minusDays(days);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateConstant.DATE);
String startDate = daysAgo.format(formatter);
String endDate = dayAgo.format(formatter);
params.put("startDate",startDate + DateConstant.TIME_START);
params.put("endDate",endDate + DateConstant.TIME_END);
String stationStr = analysisRule.getStations(); String stationStr = analysisRule.getStations();
String nuclideStr = analysisRule.getNuclides(); String nuclideStr = analysisRule.getNuclides();
// QC Flags // QC Flags
List<String> colTime = StrUtil.isNotBlank(analysisRule.getColTime()) params.putAll(this.getRuleQcFlagParams(analysisRule));
? ListUtil.toList(StrUtil.split(analysisRule.getColTime(), comma)) : null;
if(null != colTime) {
params.put("colTime", colTime);
}
List<String> acqTime = StrUtil.isNotBlank(analysisRule.getAcqTime())
? ListUtil.toList(StrUtil.split(analysisRule.getAcqTime(), comma)) : null;
if(null != acqTime) {
params.put("acqTime", acqTime);
}
List<String> xe133MDC = StrUtil.isNotBlank(analysisRule.getXe133MDC())
? ListUtil.toList(StrUtil.split(analysisRule.getXe133MDC(), comma)) : null;
if(null != xe133MDC) {
params.put("Xe133MDC", xe133MDC);
}
if(null != analysisRule.getAirFlow()) params.put("airFlow", analysisRule.getAirFlow());
if(null != analysisRule.getDecayTime()) params.put("decayTime", analysisRule.getDecayTime());
if(null != analysisRule.getSampVol()) params.put("sampVol", analysisRule.getSampVol());
if(null != analysisRule.getBa140MDC()) params.put("Ba140MDC", analysisRule.getBa140MDC());
if(null != analysisRule.getBe7FWHM()) params.put("Be7FWHM", analysisRule.getBe7FWHM());
if(null != analysisRule.getXeVol()) params.put("XeVol", analysisRule.getXeVol());
if(null != analysisRule.getXe131mFlag()) params.put("Xe131mFlag", analysisRule.getXe131mFlag());
if(null != analysisRule.getXe133mFlag()) params.put("Xe133mFlag", analysisRule.getXe133mFlag());
if(null != analysisRule.getXe133Flag()) params.put("Xe133Flag", analysisRule.getXe133Flag());
if(null != analysisRule.getXe135Flag()) params.put("Xe135Flag", analysisRule.getXe135Flag());
// 获取关注台站 // 获取关注台站
List<String> stations = ListUtil.toList(StrUtil.split(stationStr, comma)); List<String> stations = ListUtil.toList(StrUtil.split(stationStr, comma));
@ -126,89 +115,73 @@ public class CalculateConcServiceImpl implements CalculateConcService {
}else { }else {
nuclideMap.put(station, nuclides); nuclideMap.put(station, nuclides);
} }
// 查询指定台站的所有的核素浓度 并计算核素浓度均值
params.put("stationId", station);
// 获取台站类型
StationType stationType = stationType(station);
List<ConcDtoXe> xeConcAuto = new ArrayList<>();
List<ConcDtoXe> xeConcMan = new ArrayList<>();
List<ConcDto> nuclConcAuto = new ArrayList<>();
List<ConcDto> nuclConcMan = new ArrayList<>();
switch (stationType){
case BETA:
if (analysisRule.getSource().contains("1")) {
xeConcAuto = xeResultsAutoService.getConc(params, nuclides); // beta-gamma Auto
}
if(analysisRule.getSource().contains("2")){
xeConcMan = xeResultsManService.getConc(params, nuclides); // beta-gamma Man
}
break;
case GAMMA:
params.put("nuclideName", nuclides);
if (analysisRule.getSource().contains("1")) {
nuclConcAuto = nuclIdedAutoService.getConc(params); // gamma Auto
}
if(analysisRule.getSource().contains("2")){
nuclConcMan = nuclIdedManService.getConc(params); // gamma Man
}
break;
default:
break;
}
// Auto
Map<String, String> autoResult = new HashMap<>();
autoResult.putAll(calculate(concDto(xeConcAuto), coefficient));
autoResult.putAll(calculate(nuclConcAuto, coefficient));
for (String nuclide : nuclides) {
String val = autoResult.get(nuclide);
if(StrUtil.isBlank(val)) continue;
AlarmAnalysisNuclideAvg analysisNuclideAvg = new AlarmAnalysisNuclideAvg(station, nuclide, val, analysisRule.getId());
analysisNuclideAvg.setDataSourceType(CommonConstant.ARMDARR);
autoAvgs.add(analysisNuclideAvg);
}
// Man
Map<String,String> manResult = new HashMap<>();
manResult.putAll(calculate(concDto(xeConcMan), coefficient));
manResult.putAll(calculate(nuclConcMan, coefficient));
for (String nuclide : nuclides) {
String val = manResult.get(nuclide);
if(StrUtil.isBlank(val)) continue;
AlarmAnalysisNuclideAvg analysisNuclideAvg = new AlarmAnalysisNuclideAvg(station, nuclide, val, analysisRule.getId());
analysisNuclideAvg.setDataSourceType(CommonConstant.ARMDRRR);
manAvgs.add(analysisNuclideAvg);
}
} }
// 自动处理和人工交互库的台站核素浓度均值结果合并
List<AlarmAnalysisNuclideAvg> allAvgs = new ArrayList<>();
allAvgs.addAll(autoAvgs);
allAvgs.addAll(manAvgs);
// 计算周期和计算日期
String cycle = startDate + SymbolConstant.WELL_NUMBER + endDate;
allAvgs.forEach(item -> item.setCycle(cycle).setCaclDate(dayAgo));
nuclideAvgService.saveBatch(allAvgs);
// 记录日志
log.info(log(allAvgs));
} }
// 核素浓度值查询参数准备
AlarmAnalysisNuclideParam paramLatest = nuclideParamService.getLatest();
BigDecimal index = paramLatest.getIndex();
Integer days = paramLatest.getDays();
LocalDate dayAgo = LocalDate.now().minusDays(1);
LocalDate daysAgo = dayAgo.minusDays(days);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateConstant.DATE);
String startDate = daysAgo.format(formatter);
String endDate = dayAgo.format(formatter);
params.put("startDate",startDate + DateConstant.TIME_START);
params.put("endDate",endDate + DateConstant.TIME_END);
List<AlarmAnalysisNuclideAvg> autoAvgs = new ArrayList<>(); // Auto
List<AlarmAnalysisNuclideAvg> manAvgs = new ArrayList<>(); // Man
// 遍历所有台站 计算每个台站的所有核素浓度均值
init();
for (Map.Entry<String, Set<String>> entry : nuclideMap.entrySet()) {
String station = entry.getKey();
Set<String> nuclides = entry.getValue();
// 查询指定台站的所有的核素浓度 并计算核素浓度均值
params.put("stationId", station);
StationType stationType = stationType(station);
List<ConcDtoXe> xeConcAuto = new ArrayList<>();
List<ConcDtoXe> xeConcMan = new ArrayList<>();
List<ConcDto> nuclConcAuto = new ArrayList<>();
List<ConcDto> nuclConcMan = new ArrayList<>();
switch (stationType){
case BETA:
xeConcAuto = xeResultsAutoService.getConc(params, nuclides); // beta-gamma Auto
xeConcMan = xeResultsManService.getConc(params, nuclides); // beta-gamma Man
break;
case GAMMA:
params.put("nuclideName", nuclides);
nuclConcAuto = nuclIdedAutoService.getConc(params); // gamma Auto
nuclConcMan = nuclIdedManService.getConc(params); // gamma Man
break;
case NULL:
xeConcAuto = xeResultsAutoService.getConc(params, nuclides); // beta-gamma Auto
xeConcMan = xeResultsManService.getConc(params, nuclides); // beta-gamma Man
params.put("nuclideName", nuclides);
nuclConcAuto = nuclIdedAutoService.getConc(params); // gamma Auto
nuclConcMan = nuclIdedManService.getConc(params); // gamma Man
break;
default:
break;
}
// Auto
Map<String, String> autoResult = new HashMap<>();
autoResult.putAll(calculate(concDto(xeConcAuto), index));
autoResult.putAll(calculate(nuclConcAuto, index));
for (String nuclide : nuclides) {
String val = autoResult.get(nuclide);
if(StrUtil.isBlank(val)) continue;
AlarmAnalysisNuclideAvg analysisNuclideAvg = new AlarmAnalysisNuclideAvg(station, nuclide, val);
analysisNuclideAvg.setDataSourceType(CommonConstant.ARMDARR);
autoAvgs.add(analysisNuclideAvg);
}
// Man
Map<String,String> manResult = new HashMap<>();
manResult.putAll(calculate(concDto(xeConcMan), index));
manResult.putAll(calculate(nuclConcMan, index));
for (String nuclide : nuclides) {
String val = manResult.get(nuclide);
if(StrUtil.isBlank(val)) continue;
AlarmAnalysisNuclideAvg analysisNuclideAvg = new AlarmAnalysisNuclideAvg(station, nuclide, val);
analysisNuclideAvg.setDataSourceType(CommonConstant.ARMDRRR);
manAvgs.add(analysisNuclideAvg);
}
}
// 自动处理和人工交互库的台站核素浓度均值结果合并
List<AlarmAnalysisNuclideAvg> allAvgs = new ArrayList<>();
allAvgs.addAll(autoAvgs);
allAvgs.addAll(manAvgs);
// 计算周期和计算日期
String cycle = startDate + SymbolConstant.WELL_NUMBER + endDate;
allAvgs.forEach(item -> item.setCycle(cycle).setCaclDate(dayAgo));
nuclideAvgService.saveBatch(allAvgs);
// 记录日志
log.info(log(allAvgs));
}catch (Exception e){ }catch (Exception e){
log.error("NucliedAvgJob执行异常: ", e); log.error("NucliedAvgJob执行异常: ", e);
} }
@ -229,11 +202,20 @@ public class CalculateConcServiceImpl implements CalculateConcService {
.sorted(Comparator.comparing(ConcDto::getAnalysisBegin)) .sorted(Comparator.comparing(ConcDto::getAnalysisBegin))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (CollUtil.isEmpty(values)) continue; if (CollUtil.isEmpty(values)) continue;
int baseLine = values.size(); /**int baseLine = values.size();
BigDecimal line = new BigDecimal(baseLine); BigDecimal line = new BigDecimal(baseLine);
int i = line.multiply(index).setScale(0, RoundingMode.HALF_UP).intValue(); int i = line.multiply(index).setScale(0, RoundingMode.HALF_UP).intValue();
int j = Math.max(i - 1, 0); int j = Math.max(i - 1, 0);
result.put(nuclide, values.get(j).getConc()); result.put(nuclide, values.get(j).getConc());**/
// 改为求conc平均值 fix: 20250102 xiao
double sum = 0;
for (ConcDto dto : values) {
sum += Double.valueOf(dto.getConc());
}
BigDecimal avg = index.multiply(new BigDecimal(sum / values.size()));
result.put(nuclide, String.valueOf(avg.doubleValue()));
} }
return result; return result;
} }
@ -283,4 +265,44 @@ public class CalculateConcServiceImpl implements CalculateConcService {
return StationType.BETA; return StationType.BETA;
return StationType.GAMMA; return StationType.GAMMA;
} }
/**
* 获取报警规则中QC质量筛选参数
* @param analysisRule
* @return
*/
private Map<String, Object> getRuleQcFlagParams(AlarmAnalysisRule analysisRule){
Map<String,Object> params = new HashMap<>();
List<String> colTime = StrUtil.isNotBlank(analysisRule.getColTime())
? ListUtil.toList(StrUtil.split(analysisRule.getColTime(), SymbolConstant.COMMA)) : null;
if(null != colTime) {
params.put("colTime", colTime);
}
List<String> acqTime = StrUtil.isNotBlank(analysisRule.getAcqTime())
? ListUtil.toList(StrUtil.split(analysisRule.getAcqTime(), SymbolConstant.COMMA)) : null;
if(null != acqTime) {
params.put("acqTime", acqTime);
}
List<String> xe133MDC = StrUtil.isNotBlank(analysisRule.getXe133MDC())
? ListUtil.toList(StrUtil.split(analysisRule.getXe133MDC(), SymbolConstant.COMMA)) : null;
if(null != xe133MDC) {
params.put("Xe133MDC", xe133MDC);
}
if(null != analysisRule.getAirFlow()) params.put("airFlow", analysisRule.getAirFlow());
if(null != analysisRule.getDecayTime()) params.put("decayTime", analysisRule.getDecayTime());
if(null != analysisRule.getSampVol()) params.put("sampVol", analysisRule.getSampVol());
if(null != analysisRule.getBa140MDC()) params.put("Ba140MDC", analysisRule.getBa140MDC());
if(null != analysisRule.getBe7FWHM()) params.put("Be7FWHM", analysisRule.getBe7FWHM());
if(null != analysisRule.getXeVol()) params.put("XeVol", analysisRule.getXeVol());
if(null != analysisRule.getXe131mFlag()) params.put("Xe131mFlag", analysisRule.getXe131mFlag());
if(null != analysisRule.getXe133mFlag()) params.put("Xe133mFlag", analysisRule.getXe133mFlag());
if(null != analysisRule.getXe133Flag()) params.put("Xe133Flag", analysisRule.getXe133Flag());
if(null != analysisRule.getXe135Flag()) params.put("Xe135Flag", analysisRule.getXe135Flag());
return params;
}
} }