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 index 86e89dc..b109792 100644 --- 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 @@ -25,10 +25,14 @@ public class NuclideActConcIntvl { */ private String sampleType; - /** 台站编码 + /** 台站ID * */ private Integer stationId; + /** 台站编码 + * + */ + private String stationCode; /**数据源 * 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 index a640613..27da943 100644 --- 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 @@ -373,12 +373,16 @@ t1.COLLECT_STOP AS collectStop, t1.SAMPLE_TYPE AS sampleType, t1.STATION_ID AS stationId, + s.STATION_CODE AS stationCode, t1.STATUS AS status, - TO_NUMBER(REGEXP_REPLACE(t2.MDC, '[^0-9.Ee-]', '')) AS MDC, + CAST(REGEXP_REPLACE(t2.MDC, '[^0-9.Ee+-]', '') AS BINARY_DOUBLE) AS MDC, t2.NUCLIDENAME AS NUCLIDE_NAME, - TO_NUMBER(REGEXP_REPLACE(t2.CONCENTRATION, '[^0-9.Ee-]', '')) AS conc + CAST(REGEXP_REPLACE(t2.CONCENTRATION, '[^0-9.Ee+-]', '') AS BINARY_DOUBLE) AS conc, + '0' as concErr FROM ORIGINAL.GARDS_SAMPLE_DATA t1 + LEFT JOIN CONFIGURATION.GARDS_STATIONS s + ON t1.STATION_ID = s.STATION_ID LEFT JOIN RNAUTO.GARDS_NUCL_IDED t2 ON t1.SAMPLE_ID = t2.SAMPLE_ID @@ -398,12 +402,16 @@ t1.COLLECT_STOP AS collectStop, t1.SAMPLE_TYPE AS sampleType, t1.STATION_ID AS stationId, + s.STATION_CODE AS stationCode, t1.STATUS AS status, t3.MDC AS MDC, t3.NUCLIDE_NAME AS NUCLIDE_NAME, - t3.CONC AS conc + t3.CONC AS conc, + t3.CONC_ERR as concErr FROM ORIGINAL.GARDS_SAMPLE_DATA t1 + LEFT JOIN CONFIGURATION.GARDS_STATIONS s + ON t1.STATION_ID = s.STATION_ID LEFT JOIN RNAUTO.GARDS_XE_RESULTS t3 ON t1.SAMPLE_ID = t3.SAMPLE_ID @@ -430,12 +438,16 @@ t1.COLLECT_STOP AS collectStop, t1.SAMPLE_TYPE AS sampleType, t1.STATION_ID AS stationId, + s.STATION_CODE AS stationCode, t1.STATUS AS status, - TO_NUMBER(REGEXP_REPLACE(t2.MDC, '[^0-9.Ee-]', '')) AS MDC, + CAST(REGEXP_REPLACE(t2.MDC, '[^0-9.Ee+-]', '') AS BINARY_DOUBLE) AS MDC, t2.NUCLIDENAME AS NUCLIDE_NAME, - TO_NUMBER(REGEXP_REPLACE(t2.CONCENTRATION, '[^0-9.Ee-]', '')) AS conc + CAST(REGEXP_REPLACE(t2.CONCENTRATION, '[^0-9.Ee+-]', '') AS BINARY_DOUBLE) AS conc, + '0' as concErr FROM ORIGINAL.GARDS_SAMPLE_DATA t1 + LEFT JOIN CONFIGURATION.GARDS_STATIONS s + ON t1.STATION_ID = s.STATION_ID LEFT JOIN RNMAN.GARDS_NUCL_IDED t2 ON t1.SAMPLE_ID = t2.SAMPLE_ID @@ -455,12 +467,16 @@ t1.COLLECT_STOP AS collectStop, t1.SAMPLE_TYPE AS sampleType, t1.STATION_ID AS stationId, + s.STATION_CODE AS stationCode, t1.STATUS AS status, t3.MDC AS MDC, t3.NUCLIDE_NAME AS NUCLIDE_NAME, - t3.CONC AS conc + t3.CONC AS conc, + t3.CONC_ERR as concErr FROM ORIGINAL.GARDS_SAMPLE_DATA t1 + LEFT JOIN CONFIGURATION.GARDS_STATIONS s + ON t1.STATION_ID = s.STATION_ID LEFT JOIN RNMAN.GARDS_XE_RESULTS t3 ON t1.SAMPLE_ID = t3.SAMPLE_ID 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 index ffe7c10..3197642 100644 --- 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 @@ -4,29 +4,44 @@ import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.util.DateUtils; +import org.jeecg.common.util.RedisUtil; import org.jeecg.entity.*; import org.jeecg.mapper.SysDefaultNuclideMapper; import org.jeecg.modules.base.entity.original.GardsSampleData; import org.jeecg.mapper.GardsSampleStatAnalysisMapper; import org.jeecg.service.ISampleStatAnalysisService; import org.jeecg.util.DistributionAnalysisToolkit; +import org.jeecg.vo.NuclideActConcIntvlVO; import org.jeecg.vo.StationInfoVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.text.SimpleDateFormat; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; - +@Slf4j @Service @DS("ora") public class SampleStatAnalysisService extends ServiceImpl implements ISampleStatAnalysisService { + private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd"); + // 动态颜色调色板(台站动态时自动循环) + private static final String[] DETECTION_COLORS = { + "#0066ff", "#ff0000", "#ff00ff", "#00ffff", "#ffff00", "#ff9900", "#99ff00", "#9900ff" + }; + private static final String[] MDC_COLORS = { + "#aaaa00", "#ff6666", "#ff99ff", "#66ffff", "#cccc00", "#ffcc66", "#ccff66", "#cc99ff" + }; + + @Autowired + private RedisUtil redisUtil; @Autowired private SysDefaultNuclideMapper defaultNuclideMapper; @@ -290,6 +305,7 @@ public class SampleStatAnalysisService extends ServiceImpl resultMap = new HashMap<>(); @@ -378,7 +394,8 @@ public class SampleStatAnalysisService extends ServiceImpl nuclideActConcIntvls = new ArrayList<>(); Result result = new Result(); + String unit = "P".equals(sampleType) ? "μBq/m³" : "mBq/m³"; try { result.setCode(CommonConstant.SC_OK_200); @@ -520,7 +539,10 @@ public class SampleStatAnalysisService extends ServiceImpl nuclideActConcIntvls, Date startDate, Date endDate, String unit) { + if (nuclideActConcIntvls == null || nuclideActConcIntvls.isEmpty()) { + return new NuclideActConcIntvlVO(); + } + NuclideActConcIntvlVO vo = new NuclideActConcIntvlVO(); + //设置核素名称 + vo.setNuclideName(nuclideActConcIntvls.get(0).getNuclideName()); + vo.setStartTime(startDate); + vo.setEndTime(endDate); + vo.setUnit(unit); + // 按 stationCode 分组 + Map> groupByStation = nuclideActConcIntvls.stream() + .collect(Collectors.groupingBy(NuclideActConcIntvl::getStationCode)); + + int colorIndex = 0; + + + for (Map.Entry> entry : groupByStation.entrySet()) { + String displayCode = entry.getKey(); + List records = entry.getValue(); + + NuclideActConcIntvlVO.StationSeries series = new NuclideActConcIntvlVO.StationSeries(); + + String stationCode = records.stream() + .findFirst() + .map(record -> record.getStationId() != null ? record.getStationId().toString() : null) + .orElse("UNKNOWN"); + series.setStationCode(stationCode); + series.setStationName(displayCode); // 可后续扩展 + + series.setSampleCount(records.size()); + + // 动态分配颜色 + String detectionColor = DETECTION_COLORS[colorIndex % DETECTION_COLORS.length]; + String mdcColor = MDC_COLORS[colorIndex % MDC_COLORS.length]; + series.setDetectionColor(detectionColor); + series.setMdcColor(mdcColor); + colorIndex++; + + // 构建数据点 + for (NuclideActConcIntvl r : records) { + String timeStr = SDF.format(r.getCollectStop()); + + // MDC 线(始终添加) + Map mdcPoint = new HashMap<>(); + mdcPoint.put("x", timeStr); + mdcPoint.put("y", r.getMdc()); + series.getMdcData().add(mdcPoint); + + //series.getMdcData().add(new Object[]{timeStr, r.getMdc()}); + + // 检测值 + 误差条 + Double conc = r.getConc(); + Double err = r.getConcErr(); + if (conc != null && err != null) { + double low = Math.max(conc - err, 0.01); + double high = conc + err; + + Map detectionPoint = new HashMap<>(); + detectionPoint.put("x", timeStr); + detectionPoint.put("y", conc); // 中心值 + detectionPoint.put("low", low); // 下限(可选,方便前端) + detectionPoint.put("high", high); // 上限(可选) + + // 或者用: value + error 结构(ECharts 某些系列支持) + //detectionPoint.put("value", new double[]{conc, low, high}); + + series.getDetectionDataWithError().add(detectionPoint); + } + // 无有效检测时不添加点(保持图表干净) + } + + vo.getStations().add(series); + } + + return vo; + + } + + @Override public List findStationListByMenuName(String systemType) { List gardsStations = new LinkedList<>(); diff --git a/jeecg-module-data-analyze/src/main/java/org/jeecg/vo/NuclideActConcIntvlVO.java b/jeecg-module-data-analyze/src/main/java/org/jeecg/vo/NuclideActConcIntvlVO.java new file mode 100644 index 0000000..f74bcbf --- /dev/null +++ b/jeecg-module-data-analyze/src/main/java/org/jeecg/vo/NuclideActConcIntvlVO.java @@ -0,0 +1,77 @@ +package org.jeecg.vo; + + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 核素活度浓度对比图表返回 VO + * 支持图形化误差条 + */ +@Data +public class NuclideActConcIntvlVO { + + /** 图表标题 */ + private String title = "核素活度浓度对比分析"; + + /** 数据开始时间 */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date startTime; + + /** 数据结束时间 */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date endTime; + + /** 当前核素名称 */ + private String nuclideName; + + /** 单位(固定或动态) */ + private String unit = "μBq/m³"; + + /** 台站系列列表 */ + private List stations=new ArrayList<>(); + + /** + * 单个台站的图表数据 + */ + @Data + public static class StationSeries { + + /** 台站编码(如 AUX04) */ + private String stationCode; + + /** 台站名称(可选) */ + private String stationName; + + /** 样本数量(图例括号显示) */ + private Integer sampleCount; + + /** MDC 线颜色 */ + private String mdcColor; + + /** 检测值主颜色(散点和误差条) */ + private String detectionColor; + + /** + * MDC 数据:[[时间, 值], ...] + */ + private List> mdcData=new ArrayList<>(); + + /** + * 检测值带误差条的数据(核心变更) + * 每个点格式:[时间字符串, 中心值(conc), 下限值(conc - err), 上限值(conc + err)] + * - 如果无检测或低于 MDC:整个数组为 null + * - 支持非对称误差(下限/上限可不同) + * - 前端 ECharts 可直接用此格式绘制误差条(推荐方式) + */ + private List> detectionDataWithError =new ArrayList<>(); + } +} \ No newline at end of file