From ea2778ce4e960ceeb654d970177b7c9ad4ec4f87 Mon Sep 17 00:00:00 2001 From: wxr Date: Tue, 10 Mar 2026 10:50:49 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B6=85=E5=B7=AE=E5=88=A4=E5=AE=9A=E7=AD=89?= =?UTF-8?q?=E5=86=8D=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/qms/enums/QmsCommonConstant.java | 9 + .../admin/SampleAnalysisAuditController.java | 4 +- .../BusinessAssayProjectDataExtendRespVO.java | 3 + .../vo/BusinessAssayProjectDataPageReqVO.java | 6 + .../vo/BusinessAssayProjectDataReqVO.java | 6 + .../vo/BusinessAssayProjectDataRespVO.java | 9 +- .../vo/BusinessAssayProjectDataSaveReqVO.java | 6 + .../BusinessSubSampleAssessmentPageReqVO.java | 3 + .../vo/BusinessSubSampleAssessmentRespVO.java | 3 + .../BusinessSubSampleAssessmentSaveReqVO.java | 3 + .../BusinessAssayProjectDataDO.java | 10 + .../BusinessSubSampleAssessmentDO.java | 5 + .../BusinessAssayProjectDataMapper.java | 6 +- .../BusinessSubSampleAssessmentMapper.java | 2 + .../SampleAnalysisAuditServiceImpl.java | 1042 ++++++----------- .../service/SampleAnalysisServiceImpl.java | 4 +- ...AssayMethodProjectAssessmentPageReqVO.java | 6 + ...figAssayMethodProjectAssessmentRespVO.java | 6 + ...AssayMethodProjectAssessmentSaveReqVO.java | 6 + .../ConfigAssayMethodProjectAssessmentDO.java | 10 + ...figAssayMethodProjectAssessmentMapper.java | 2 + 21 files changed, 456 insertions(+), 695 deletions(-) diff --git a/zt-module-qms/zt-module-qms-api/src/main/java/com/zt/plat/module/qms/enums/QmsCommonConstant.java b/zt-module-qms/zt-module-qms-api/src/main/java/com/zt/plat/module/qms/enums/QmsCommonConstant.java index 85387df7..cafa9fb4 100644 --- a/zt-module-qms/zt-module-qms-api/src/main/java/com/zt/plat/module/qms/enums/QmsCommonConstant.java +++ b/zt-module-qms/zt-module-qms-api/src/main/java/com/zt/plat/module/qms/enums/QmsCommonConstant.java @@ -187,6 +187,15 @@ public interface QmsCommonConstant { /** 结果判定-已上报 */ String ASMT_REPORTED = "reported"; + + /** 超差判断类型:内控 **/ + String ASMT_TYPE_INTERNAL_CONTROL = "internalControl"; + + /** 超差判断类型:重复性 **/ + String ASMT_TYPE_REPETITIVENESS = "repetitiveness"; + + /** 超差判断类型:再现性 **/ + String ASMT_TYPE_REPRODUCIBILITY = "reproducibility"; /** 检验完成状态-完成 **/ String CHECKED = "checked"; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/admin/SampleAnalysisAuditController.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/admin/SampleAnalysisAuditController.java index 1314dd44..d32ea562 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/admin/SampleAnalysisAuditController.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/admin/SampleAnalysisAuditController.java @@ -104,8 +104,8 @@ public class SampleAnalysisAuditController implements BusinessControllerMarker { //重新创建复检委托 @PostMapping("/createReAnalysis") - public CommonResult createReAnalysis(Long businessSubSampleId, Long configAssayMethodId, Integer retestCount) { - sampleAnalysisAuditService.createReAnalysis(businessSubSampleId, configAssayMethodId, retestCount); + public CommonResult createReAnalysis(Long businessSubSampleId, Long configAssayMethodId, Integer retestCount, Integer taskCount) { + sampleAnalysisAuditService.createReAnalysis(businessSubSampleId, configAssayMethodId, retestCount, taskCount); return success("成功"); } diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataExtendRespVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataExtendRespVO.java index 961eefa1..53321205 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataExtendRespVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataExtendRespVO.java @@ -53,4 +53,7 @@ public class BusinessAssayProjectDataExtendRespVO extends BusinessAssayProjectDa @Schema(description = "复测次数") private Integer retestCount; + + @Schema(description = "判定类型名称") + private String assessmentTypeName; } diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataPageReqVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataPageReqVO.java index 476a26dd..41830992 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataPageReqVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataPageReqVO.java @@ -57,6 +57,12 @@ public class BusinessAssayProjectDataPageReqVO extends PageParam { @Schema(description = "方法检出下限值") private String minimumLimitValue; + @Schema(description = "判定类型,内控超差、重复性超差、再现性超差", example = "2") + private String assessmentType; + + @Schema(description = "是否作废(取消)判定[超差时],1-是,0-否") + private Integer isCancelAssessment; + @Schema(description = "是否启用") private Integer isEnabled; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataReqVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataReqVO.java index a34fc31f..cf85b7eb 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataReqVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataReqVO.java @@ -63,6 +63,12 @@ public class BusinessAssayProjectDataReqVO { @Schema(description = "方法检出下限值") private String minimumLimitValue; + @Schema(description = "判定类型,内控超差、重复性超差、再现性超差", example = "2") + private String assessmentType; + + @Schema(description = "是否作废(取消)判定[超差时],1-是,0-否") + private Integer isCancelAssessment; + @Schema(description = "是否启用") private Integer isEnabled; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataRespVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataRespVO.java index dcb9d5e6..7a91f54e 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataRespVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataRespVO.java @@ -2,9 +2,6 @@ package com.zt.plat.module.qms.business.bus.controller.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import java.util.*; -import org.springframework.format.annotation.DateTimeFormat; - import java.math.BigDecimal; import java.time.LocalDateTime; import com.alibaba.excel.annotation.*; @@ -67,6 +64,12 @@ public class BusinessAssayProjectDataRespVO { @Schema(description = "方法检出下限值") private String minimumLimitValue; + @Schema(description = "判定类型,内控超差、重复性超差、再现性超差", example = "2") + private String assessmentType; + + @Schema(description = "是否作废(取消)判定[超差时],1-是,0-否") + private Integer isCancelAssessment; + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("是否启用") private Integer isEnabled; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataSaveReqVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataSaveReqVO.java index 97369804..5927b62d 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataSaveReqVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessAssayProjectDataSaveReqVO.java @@ -55,6 +55,12 @@ public class BusinessAssayProjectDataSaveReqVO { @Schema(description = "方法检出下限值") private String minimumLimitValue; + @Schema(description = "判定类型,内控超差、重复性超差、再现性超差", example = "2") + private String assessmentType; + + @Schema(description = "是否作废(取消)判定[超差时],1-是,0-否") + private Integer isCancelAssessment; + @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "是否启用不能为空") private Integer isEnabled; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentPageReqVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentPageReqVO.java index 41be175b..c3a4814e 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentPageReqVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentPageReqVO.java @@ -50,6 +50,9 @@ public class BusinessSubSampleAssessmentPageReqVO extends PageParam { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] reportTime; + @Schema(description = "上报描述") + private String reportDescription; + @Schema(description = "结果处理方式,automatic-自动报出(不超差),manual-手动报出,modify-允许修改") private String resultTreatmentWay; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentRespVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentRespVO.java index e6ebc54f..27697d56 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentRespVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentRespVO.java @@ -62,6 +62,9 @@ public class BusinessSubSampleAssessmentRespVO { @ExcelProperty("上报时间") private LocalDateTime reportTime; + @Schema(description = "上报描述") + private String reportDescription; + @Schema(description = "结果处理方式,automatic-自动报出(不超差),manual-手动报出,modify-允许修改") private String resultTreatmentWay; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentSaveReqVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentSaveReqVO.java index d9962036..965d7642 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentSaveReqVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/controller/vo/BusinessSubSampleAssessmentSaveReqVO.java @@ -53,6 +53,9 @@ public class BusinessSubSampleAssessmentSaveReqVO { @Schema(description = "上报时间") private LocalDateTime reportTime; + @Schema(description = "上报描述") + private String reportDescription; + @Schema(description = "结果处理方式,automatic-自动报出(不超差),manual-手动报出,modify-允许修改") private String resultTreatmentWay; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/dataobject/BusinessAssayProjectDataDO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/dataobject/BusinessAssayProjectDataDO.java index e82045f4..f9497d9b 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/dataobject/BusinessAssayProjectDataDO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/dataobject/BusinessAssayProjectDataDO.java @@ -97,6 +97,16 @@ public class BusinessAssayProjectDataDO extends BusinessBaseDO { @TableField("IS_NT_ASMT") private Integer isNotAssessment; /** + * 判定类型,内控超差、重复性超差、再现性超差 + */ + @TableField("ASMT_TP") + private String assessmentType; + /** + * 是否作废(取消)判定[超差时],1-是,0-否 + */ + @TableField("IS_CNL_ASMT") + private Integer isCancelAssessment; + /** * 是否启用 */ @TableField("IS_ENBD") diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/dataobject/BusinessSubSampleAssessmentDO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/dataobject/BusinessSubSampleAssessmentDO.java index 01b5c6ee..4821bc23 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/dataobject/BusinessSubSampleAssessmentDO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/dataobject/BusinessSubSampleAssessmentDO.java @@ -101,6 +101,11 @@ public class BusinessSubSampleAssessmentDO extends BusinessBaseDO { @TableField("RPT_TM") private LocalDateTime reportTime; /** + * 上报描述 + */ + @TableField("RPT_DSP") + private String reportDescription; + /** * 结果处理方式,automatic-自动报出(不超差),manual-手动报出,modify-允许修改 */ @TableField("RSLT_TMT_WY") diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/mapper/BusinessAssayProjectDataMapper.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/mapper/BusinessAssayProjectDataMapper.java index 9293425f..da391199 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/mapper/BusinessAssayProjectDataMapper.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/mapper/BusinessAssayProjectDataMapper.java @@ -135,6 +135,8 @@ public interface BusinessAssayProjectDataMapper extends BaseMapperX selectAssayMethodProjectByBusinessSubSampleIdListAndConfigAssayMethodId(@Param("businessSubSampleIdList")List businessSubSampleIdList, @Param("configAssayMethodId") Long configAssayMethodId); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/mapper/BusinessSubSampleAssessmentMapper.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/mapper/BusinessSubSampleAssessmentMapper.java index ae3ff6b3..b5fc7cd5 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/mapper/BusinessSubSampleAssessmentMapper.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/dal/mapper/BusinessSubSampleAssessmentMapper.java @@ -31,6 +31,8 @@ public interface BusinessSubSampleAssessmentMapper extends BaseMapperX c >= 2); +// boolean isMultitask = assayOperatorCountMap.values().stream().allMatch(c -> c >= 2); //不是复检 if (!isRecheck) { - if (assayOperatorSize == 1) {//单人 - if (isMultitask) {//多任务 重复性 + //优先查询内控,如果存在内控,则使用内控超差判定,否则根据人数确定 + //查询内控超差配置 + List internalControlConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL.equals(f.getAssessmentType())).collect(Collectors.toList()); + if (internalControlConfigAssayMethodProjectAssessmentDOList.size() > 0) { + // 排序并处理 null + List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) + .map(v -> { + String val = v.getValueAfter();//补正后的值 + return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); + }) + .sorted() + .collect(Collectors.toList()); + List vBySortedValues = val1.stream() + .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) + // 构建 Entry: Key是原对象,Value是排序用的数字 + .map(v -> { + String valStr = v.getValueAfter(); + BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) + ? BigDecimal.ZERO + : new BigDecimal(valStr.trim()); + return new SimpleEntry<>(v, sortVal); + }) + // 比较 Entry 的 Value 部分 + .sorted(Map.Entry.comparingByValue()) + // 提取 Key (原对象) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + + // 获取小数精度 + int elementScale = businessAssayProjectDataDO.getDecimalPosition(); + //获取有效位数 + int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); + // 计算代表值(均值或差值) + BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); + + //计算后保留有效位数 + representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); + //设置判定值 + businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); + + // 查找匹配的允差规则 + ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(internalControlConfigAssayMethodProjectAssessmentDOList, representativeValue); + if (matchedRule == null) { + throw new ServiceException(1_032_100_000, "未找到内控超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); + } + + // 计算允差值 + BigDecimal allowValue; + try { + allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); + } catch (Exception e) { + throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); + } + + // 判断相邻差值是否超差 + for (int i = 0; i < sortedValues.size() - 1; i++) { + BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); + BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); + BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); + if (diff.compareTo(allowValue) > 0) { + businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); + preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); + curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); + preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); + curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); + + //存在超差,设置为待判定 + if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { + businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); + } + } else { + preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); + curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); + } + } + } else { + if (assayOperatorSize == 1) {//如果是单人,使用重复性。 //过滤配置为 重复性超差 List repetitivenessConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_REPETITIVENESS.equals(f.getAssessmentType())).collect(Collectors.toList()); if (repetitivenessConfigAssayMethodProjectAssessmentDOList.size() > 0) { @@ -856,10 +931,10 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic // 判断相邻差值是否超差 for (int i = 0; i < sortedValues.size() - 1; i++) { BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); + BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); + BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); if (diff.compareTo(allowValue) > 0) { businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); int isCancelAssessment = matchedRule.getIsCancelAssessment();//查询配置,是否超差 @@ -875,267 +950,18 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); } - } + } else { + preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); + curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); + } } + } else { + throw new ServiceException(1_032_100_000, "单人,未找到重复性超差判定配置! "); } - } - } else { - if (isMultitask) {//多人,多任务 单人任务先重复性,再多人任务再现性 - //查询重复性判定配置 - List repetitivenessConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_REPETITIVENESS.equals(f.getAssessmentType())).collect(Collectors.toList()); - if (repetitivenessConfigAssayMethodProjectAssessmentDOList.size() > 0) { - //分析人员分组,先单人任务进行重复性判定 - Map> assayOperatorMap = val1.stream().collect(Collectors.groupingBy(BusinessAssayProjectDataExtendRespVO::getAssayOperator)); - for (Map.Entry> entry : assayOperatorMap.entrySet()) { - String assayOperator = entry.getKey(); - Log.debug(assayOperator + "的重复性判定"); - List assayOperatorValue = entry.getValue(); - // 排序并处理 null - List sortedValues = assayOperatorValue.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - .map(v -> { - String val = v.getValueAfter();//补正后的值 - return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); - }) - .sorted() - .collect(Collectors.toList()); - List vBySortedValues = assayOperatorValue.stream() - .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - // 构建 Entry: Key是原对象,Value是排序用的数字 - .map(v -> { - String valStr = v.getValueAfter(); - BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) - ? BigDecimal.ZERO - : new BigDecimal(valStr.trim()); - return new SimpleEntry<>(v, sortVal); - }) - // 比较 Entry 的 Value 部分 - .sorted(Map.Entry.comparingByValue()) - // 提取 Key (原对象) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - // 获取小数精度 - int elementScale = businessAssayProjectDataDO.getDecimalPosition(); - //获取有效位数 - int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); - // 计算代表值(均值或差值) - BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); - - //计算后保留有效位数 - representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); - //设置判定值 - businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); - - // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(repetitivenessConfigAssayMethodProjectAssessmentDOList, representativeValue); - if (matchedRule == null) { - throw new ServiceException(1_032_100_000, "未找到重复性超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); - } - - // 计算允差值 - BigDecimal allowValue; - try { - allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); - } catch (Exception e) { - throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); - } - - // 判断相邻差值是否超差 - for (int i = 0; i < sortedValues.size() - 1; i++) { - BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); - if (diff.compareTo(allowValue) > 0) { - businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); - int isCancelAssessment = matchedRule.getIsCancelAssessment();//查询配置,是否超差 - if (isCancelAssessment == 1) { - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.YES); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.YES); - preBusinessAssayProjectDataDO.setIsNotAssessment(QmsCommonConstant.YES); - curBusinessAssayProjectDataDO.setIsNotAssessment(QmsCommonConstant.YES); - } else { - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - preBusinessAssayProjectDataDO.setIsNotAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsNotAssessment(QmsCommonConstant.NO); - } - - //存在超差,设置为待判定 - if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); - } - } else { - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); - } - - } - } - - if (QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { //如果重复性超差 - businessSubSampleAssessmentProjectDO.setAssessmentValue(null);//如果重复性超差,则值标记为空 - val1.forEach(item -> { - item.setIsNotAssessment(QmsCommonConstant.YES); - }); - } - } - - //如果重复性判定不超差,再进行再现性判定 - if (QmsCommonConstant.ASMT_PENDING_REPORT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - List reproducibilityConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY.equals(f.getAssessmentType())).collect(Collectors.toList()); - if (reproducibilityConfigAssayMethodProjectAssessmentDOList.size() > 0) { - // 排序并处理 null - List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - .map(v -> { - String val = v.getValueAfter();//补正后的值 - return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); - }) - .sorted() - .collect(Collectors.toList()); - List vBySortedValues = val1.stream() - .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - // 构建 Entry: Key是原对象,Value是排序用的数字 - .map(v -> { - String valStr = v.getValueAfter(); - BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) - ? BigDecimal.ZERO - : new BigDecimal(valStr.trim()); - return new SimpleEntry<>(v, sortVal); - }) - // 比较 Entry 的 Value 部分 - .sorted(Map.Entry.comparingByValue()) - // 提取 Key (原对象) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - // 获取小数精度 - int elementScale = businessAssayProjectDataDO.getDecimalPosition(); - //获取有效位数 - int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); - // 计算代表值(均值或差值) - BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); - - //计算后保留有效位数 - representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); - //设置判定值 - businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); - - // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(reproducibilityConfigAssayMethodProjectAssessmentDOList, representativeValue); - if (matchedRule == null) { - throw new ServiceException(1_032_100_000, "未找到再现性超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); - } - - // 计算允差值 - BigDecimal allowValue; - try { - allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); - } catch (Exception e) { - throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); - } - - // 判断相邻差值是否超差 - for (int i = 0; i < sortedValues.size() - 1; i++) { - BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); - if (diff.compareTo(allowValue) > 0) { - businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - - //存在超差,设置为待判定 - if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); - } - } else { - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); - } - } - } - } - } else {//多人,单任务 (内控|再现性) - //1、内控超差配置 - List internalControlConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL.equals(f.getAssessmentType())).collect(Collectors.toList()); - if (internalControlConfigAssayMethodProjectAssessmentDOList.size() > 0) { - // 排序并处理 null - List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - .map(v -> { - String val = v.getValueAfter();//补正后的值 - return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); - }) - .sorted() - .collect(Collectors.toList()); - List vBySortedValues = val1.stream() - .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - // 构建 Entry: Key是原对象,Value是排序用的数字 - .map(v -> { - String valStr = v.getValueAfter(); - BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) - ? BigDecimal.ZERO - : new BigDecimal(valStr.trim()); - return new SimpleEntry<>(v, sortVal); - }) - // 比较 Entry 的 Value 部分 - .sorted(Map.Entry.comparingByValue()) - // 提取 Key (原对象) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - // 获取小数精度 - int elementScale = businessAssayProjectDataDO.getDecimalPosition(); - //获取有效位数 - int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); - // 计算代表值(均值或差值) - BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); - - //计算后保留有效位数 - representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); - //设置判定值 - businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); - - // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(internalControlConfigAssayMethodProjectAssessmentDOList, representativeValue); - if (matchedRule == null) { - throw new ServiceException(1_032_100_000, "未找到超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); - } - - // 计算允差值 - BigDecimal allowValue; - try { - allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); - } catch (Exception e) { - throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); - } - - // 判断相邻差值是否超差 - for (int i = 0; i < sortedValues.size() - 1; i++) { - BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); - if (diff.compareTo(allowValue) > 0) { - businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - - //存在超差,设置为待判定 - if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); - } - } - } - } - - //2、再现性超差配置 + } else {//多人使用再现性 + //再现性超差配置 List reproducibilityConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY.equals(f.getAssessmentType())).collect(Collectors.toList()); - if (internalControlConfigAssayMethodProjectAssessmentDOList.size() > 0) { + if (reproducibilityConfigAssayMethodProjectAssessmentDOList.size() > 0) { // 排序并处理 null List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) .map(v -> { @@ -1189,10 +1015,10 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic // 判断相邻差值是否超差 for (int i = 0; i < sortedValues.size() - 1; i++) { BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); + BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); + BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); if (diff.compareTo(allowValue) > 0) { businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); @@ -1202,91 +1028,150 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); } - } + } else { + preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); + curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); + } } + } else { + throw new ServiceException(1_032_100_000, "多人,未找到再现性超差判定配置! "); } - - - - //3、其他(不属于内控/重复性/再现性) - List otherConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> !QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL.equals(f.getAssessmentType()) && !QmsCommonConstant.ASMT_TYPE_REPETITIVENESS.equals(f.getAssessmentType()) && !QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY.equals(f.getAssessmentType()) ).collect(Collectors.toList()); - if (otherConfigAssayMethodProjectAssessmentDOList.size() > 0) { - // 排序并处理 null - List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - .map(v -> { - String val = v.getValueAfter();//补正后的值 - return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); - }) - .sorted() - .collect(Collectors.toList()); - List vBySortedValues = val1.stream() - .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - // 构建 Entry: Key是原对象,Value是排序用的数字 - .map(v -> { - String valStr = v.getValueAfter(); - BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) - ? BigDecimal.ZERO - : new BigDecimal(valStr.trim()); - return new SimpleEntry<>(v, sortVal); - }) - // 比较 Entry 的 Value 部分 - .sorted(Map.Entry.comparingByValue()) - // 提取 Key (原对象) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - // 获取小数精度 - int elementScale = businessAssayProjectDataDO.getDecimalPosition(); - //获取有效位数 - int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); - // 计算代表值(均值或差值) - BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); - - //计算后保留有效位数 - representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); - //设置判定值 - businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); - - // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(otherConfigAssayMethodProjectAssessmentDOList, representativeValue); - if (matchedRule == null) { - throw new ServiceException(1_032_100_000, "未找到超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); - } - - // 计算允差值 - BigDecimal allowValue; - try { - allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); - } catch (Exception e) { - throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); - } - - // 判断相邻差值是否超差 - for (int i = 0; i < sortedValues.size() - 1; i++) { - BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); - if (diff.compareTo(allowValue) > 0) { - businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); - preBusinessAssayProjectDataDO.setAssessmentType(""); - curBusinessAssayProjectDataDO.setAssessmentType(""); - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - - //存在超差,设置为待判定 - if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); - } - } - } - } - - } } } else {//发起过复检的 - if (assayOperatorSize == 1) {//单人 - if (isMultitask) {//单人多任务 + //优先查询内控,如果存在内控,则使用内控超差判定,否则根据人数确定 + //查询内控超差配置 + List internalControlConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL.equals(f.getAssessmentType())).collect(Collectors.toList()); + if (internalControlConfigAssayMethodProjectAssessmentDOList.size() > 0) { + // 排序并处理 null + List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) + .map(v -> { + String val = v.getValueAfter();//补正后的值 + return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); + }) + .sorted() + .collect(Collectors.toList()); + List vBySortedValues = val1.stream() + .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) + // 构建 Entry: Key是原对象,Value是排序用的数字 + .map(v -> { + String valStr = v.getValueAfter(); + BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) + ? BigDecimal.ZERO + : new BigDecimal(valStr.trim()); + return new SimpleEntry<>(v, sortVal); + }) + // 比较 Entry 的 Value 部分 + .sorted(Map.Entry.comparingByValue()) + // 提取 Key (原对象) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + + // 获取小数精度 + int elementScale = businessAssayProjectDataDO.getDecimalPosition(); + //获取有效位数 + int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); + // 计算代表值(均值或差值) + BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); + + //计算后保留有效位数 + representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); + //设置判定值 + businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); + + // 查找匹配的允差规则 + ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(internalControlConfigAssayMethodProjectAssessmentDOList, representativeValue); + if (matchedRule == null) { + throw new ServiceException(1_032_100_000, "未找到内控超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); + } + + // 计算允差值 + BigDecimal allowValue; + try { + allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); + } catch (Exception e) { + throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); + } + + List> validGroups = new ArrayList<>(); + List currentGroup = new ArrayList<>(); + + // 判断相邻差值是否超差 + for (int i = 0; i < sortedValues.size() - 1; i++) { + BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); + BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); + BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); + if (diff.compareTo(allowValue) > 0) { + businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); + preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); + curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); + preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); + curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); + + //存在超差,设置为待判定 + if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { + businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); + } + + // 超差:当前连续序列中断 + // 检查之前积累的组是否有效 (长度 >= 2) + if (currentGroup.size() >= 2) { + validGroups.add(new ArrayList<>(currentGroup)); // 保存副本 + } + // 重置当前组,从当前元素重新开始 + currentGroup.clear(); + currentGroup.add(curBusinessAssayProjectDataDO); + } else { + preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); + curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); + + // 不超差:将当前元素加入正在积累的组 + currentGroup.add(curBusinessAssayProjectDataDO); + } + } + // 循环结束后,currentGroup 中可能还留有最后一段连续数据 + if (currentGroup.size() >= 2) { + validGroups.add(new ArrayList<>(currentGroup)); + } + + for (List group : validGroups) { + if (group.size() > val1.size()/2) { + sortedValues = group.stream() + .map(v -> { + String val = v.getValueAfter();//补正后的值 + return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); + }) + .sorted() + .collect(Collectors.toList()); + + // 计算代表值(均值或差值) + representativeValue = calculateRepresentativeValue(sortedValues, elementScale); + + //计算后保留有效位数 + representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); + //设置判定值 + businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); + businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_REPORT); + + //处理勾选 + List collect = group.stream().map(m -> m.getId()).collect(Collectors.toList()); + val1.forEach(item -> { + if (collect.contains(item.getId())) { + item.setIsNotAssessment(QmsCommonConstant.NO); + } else { + item.setIsNotAssessment(QmsCommonConstant.YES); + } + + }); + + break; + } + + } + + } else { + + if (assayOperatorSize == 1) {//如果是单人,使用重复性。 //过滤配置为 重复性超差 List repetitivenessConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_REPETITIVENESS.equals(f.getAssessmentType())).collect(Collectors.toList()); if (repetitivenessConfigAssayMethodProjectAssessmentDOList.size() > 0) { @@ -1339,14 +1224,16 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic } catch (Exception e) { throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); } + List> validGroups = new ArrayList<>(); + List currentGroup = new ArrayList<>(); // 判断相邻差值是否超差 for (int i = 0; i < sortedValues.size() - 1; i++) { BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); + BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); + BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); if (diff.compareTo(allowValue) > 0) { businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); int isCancelAssessment = matchedRule.getIsCancelAssessment();//查询配置,是否超差 @@ -1362,270 +1249,69 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); } - } - } - } - } - } else { - if (isMultitask) {//多人多任务 单人任务先重复性,再多人任务再现性 - //查询重复性判定配置 - List repetitivenessConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_REPETITIVENESS.equals(f.getAssessmentType())).collect(Collectors.toList()); - if (repetitivenessConfigAssayMethodProjectAssessmentDOList.size() > 0) { - //分析人员分组,先单人任务进行重复性判定 - Integer maxRecheckCount = val1.stream().map(m -> m.getRecheckCount()).distinct().max(Comparator.naturalOrder()).get(); - //重复性,只判定最后复检的样品 - Map> assayOperatorMap = val1.stream().filter(f -> f.getRecheckCount().equals(maxRecheckCount)).collect(Collectors.groupingBy(BusinessAssayProjectDataExtendRespVO::getAssayOperator)); - for (Map.Entry> entry : assayOperatorMap.entrySet()) { - String assayOperator = entry.getKey(); - Log.debug(assayOperator + "的重复性判定"); - List assayOperatorValue = entry.getValue(); - // 排序并处理 null - List sortedValues = assayOperatorValue.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - .map(v -> { - String val = v.getValueAfter();//补正后的值 - return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); - }) - .sorted() - .collect(Collectors.toList()); - List vBySortedValues = assayOperatorValue.stream() - .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - // 构建 Entry: Key是原对象,Value是排序用的数字 - .map(v -> { - String valStr = v.getValueAfter(); - BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) - ? BigDecimal.ZERO - : new BigDecimal(valStr.trim()); - return new SimpleEntry<>(v, sortVal); - }) - // 比较 Entry 的 Value 部分 - .sorted(Map.Entry.comparingByValue()) - // 提取 Key (原对象) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - // 获取小数精度 - int elementScale = businessAssayProjectDataDO.getDecimalPosition(); - //获取有效位数 - int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); - // 计算代表值(均值或差值) - BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); - - //计算后保留有效位数 - representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); - //设置判定值 - businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); - - // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(repetitivenessConfigAssayMethodProjectAssessmentDOList, representativeValue); - if (matchedRule == null) { - throw new ServiceException(1_032_100_000, "未找到重复性超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); - } - - // 计算允差值 - BigDecimal allowValue; - try { - allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); - } catch (Exception e) { - throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); - } - - // 判断相邻差值是否超差 - for (int i = 0; i < sortedValues.size() - 1; i++) { - BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); - if (diff.compareTo(allowValue) > 0) { - businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); - int isCancelAssessment = matchedRule.getIsCancelAssessment();//查询配置,是否超差 - if (isCancelAssessment == 1) { - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.YES); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.YES); - preBusinessAssayProjectDataDO.setIsNotAssessment(QmsCommonConstant.YES); - curBusinessAssayProjectDataDO.setIsNotAssessment(QmsCommonConstant.YES); - } else { - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - preBusinessAssayProjectDataDO.setIsNotAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsNotAssessment(QmsCommonConstant.NO); - } - - //存在超差,设置为待判定 - if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); - } - } else { - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); - } - - } - } - - if (QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { //如果重复性超差 - businessSubSampleAssessmentProjectDO.setAssessmentValue(null);//如果重复性超差,则值标记为空 - val1.forEach(item -> { - item.setIsNotAssessment(QmsCommonConstant.YES); - }); - } - } - - //如果重复性判定不超差,再进行再现性判定 - if (QmsCommonConstant.ASMT_PENDING_REPORT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - List reproducibilityConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY.equals(f.getAssessmentType())).collect(Collectors.toList()); - if (reproducibilityConfigAssayMethodProjectAssessmentDOList.size() > 0) { - // 排序并处理 null - List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - .map(v -> { - String val = v.getValueAfter();//补正后的值 - return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); - }) - .sorted() - .collect(Collectors.toList()); - List vBySortedValues = val1.stream() - .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - // 构建 Entry: Key是原对象,Value是排序用的数字 - .map(v -> { - String valStr = v.getValueAfter(); - BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) - ? BigDecimal.ZERO - : new BigDecimal(valStr.trim()); - return new SimpleEntry<>(v, sortVal); - }) - // 比较 Entry 的 Value 部分 - .sorted(Map.Entry.comparingByValue()) - // 提取 Key (原对象) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - // 获取小数精度 - int elementScale = businessAssayProjectDataDO.getDecimalPosition(); - //获取有效位数 - int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); - // 计算代表值(均值或差值) - BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); - - //计算后保留有效位数 - representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); - //设置判定值 - businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); - - // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(reproducibilityConfigAssayMethodProjectAssessmentDOList, representativeValue); - if (matchedRule == null) { - throw new ServiceException(1_032_100_000, "未找到再现性超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); - } - - // 计算允差值 - BigDecimal allowValue; - try { - allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); - } catch (Exception e) { - throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); - } - - // 判断相邻差值是否超差 - for (int i = 0; i < sortedValues.size() - 1; i++) { - BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); - if (diff.compareTo(allowValue) > 0) { - businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - - //存在超差,设置为待判定 - if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); - } - } else { - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); - } - } - } - } - - } else { //多人单任务 - //1、内控超差配置 - List internalControlConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL.equals(f.getAssessmentType())).collect(Collectors.toList()); - if (internalControlConfigAssayMethodProjectAssessmentDOList.size() > 0) { - // 排序并处理 null - List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - .map(v -> { - String val = v.getValueAfter();//补正后的值 - return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); - }) - .sorted() - .collect(Collectors.toList()); - List vBySortedValues = val1.stream() - .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - // 构建 Entry: Key是原对象,Value是排序用的数字 - .map(v -> { - String valStr = v.getValueAfter(); - BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) - ? BigDecimal.ZERO - : new BigDecimal(valStr.trim()); - return new SimpleEntry<>(v, sortVal); - }) - // 比较 Entry 的 Value 部分 - .sorted(Map.Entry.comparingByValue()) - // 提取 Key (原对象) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - // 获取小数精度 - int elementScale = businessAssayProjectDataDO.getDecimalPosition(); - //获取有效位数 - int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); - // 计算代表值(均值或差值) - BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); - - //计算后保留有效位数 - representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); - //设置判定值 - businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); - - // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(internalControlConfigAssayMethodProjectAssessmentDOList, representativeValue); - if (matchedRule == null) { - throw new ServiceException(1_032_100_000, "未找到超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); - } - - // 计算允差值 - BigDecimal allowValue; - try { - allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); - } catch (Exception e) { - throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); - } - - // 判断相邻差值是否超差 - for (int i = 0; i < sortedValues.size() - 1; i++) { - BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); - if (diff.compareTo(allowValue) > 0) { - businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); - preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); - curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL); - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - //存在超差,设置为待判定 - if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); - } - } + // 超差:当前连续序列中断 + // 检查之前积累的组是否有效 (长度 >= 2) + if (currentGroup.size() >= 2) { + validGroups.add(new ArrayList<>(currentGroup)); // 保存副本 + } + // 重置当前组,从当前元素重新开始 + currentGroup.clear(); + currentGroup.add(curBusinessAssayProjectDataDO); + } else { + preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); + curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPETITIVENESS); + + // 不超差:将当前元素加入正在积累的组 + currentGroup.add(curBusinessAssayProjectDataDO); + } } + // 循环结束后,currentGroup 中可能还留有最后一段连续数据 + if (currentGroup.size() >= 2) { + validGroups.add(new ArrayList<>(currentGroup)); + } + + for (List group : validGroups) { + if (group.size() > val1.size()/2) { + sortedValues = group.stream() + .map(v -> { + String val = v.getValueAfter();//补正后的值 + return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); + }) + .sorted() + .collect(Collectors.toList()); + + // 计算代表值(均值或差值) + representativeValue = calculateRepresentativeValue(sortedValues, elementScale); + + //计算后保留有效位数 + representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); + //设置判定值 + businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); + businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_REPORT); + + //处理勾选 + List collect = group.stream().map(m -> m.getId()).collect(Collectors.toList()); + val1.forEach(item -> { + if (collect.contains(item.getId())) { + item.setIsNotAssessment(QmsCommonConstant.NO); + } else { + item.setIsNotAssessment(QmsCommonConstant.YES); + } + + }); + + break; + } + + } + } else { + throw new ServiceException(1_032_100_000, "单人,未找到重复性超差判定配置! "); } - - //2、再现性超差配置 + } else {//多人使用再现性 + //再现性超差配置 List reproducibilityConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY.equals(f.getAssessmentType())).collect(Collectors.toList()); - if (internalControlConfigAssayMethodProjectAssessmentDOList.size() > 0) { + if (reproducibilityConfigAssayMethodProjectAssessmentDOList.size() > 0) { // 排序并处理 null List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) .map(v -> { @@ -1675,14 +1361,16 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic } catch (Exception e) { throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); } + List> validGroups = new ArrayList<>(); + List currentGroup = new ArrayList<>(); // 判断相邻差值是否超差 for (int i = 0; i < sortedValues.size() - 1; i++) { BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); + BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); + BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); if (diff.compareTo(allowValue) > 0) { businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); @@ -1692,86 +1380,65 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); } - } - } - } - - - - //3、其他(不属于内控/重复性/再现性) - List otherConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> !QmsCommonConstant.ASMT_TYPE_INTERNAL_CONTROL.equals(f.getAssessmentType()) && !QmsCommonConstant.ASMT_TYPE_REPETITIVENESS.equals(f.getAssessmentType()) && !QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY.equals(f.getAssessmentType()) ).collect(Collectors.toList()); - if (otherConfigAssayMethodProjectAssessmentDOList.size() > 0) { - // 排序并处理 null - List sortedValues = val1.stream().filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - .map(v -> { - String val = v.getValueAfter();//补正后的值 - return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); - }) - .sorted() - .collect(Collectors.toList()); - List vBySortedValues = val1.stream() - .filter(f -> f.getIsCancelAssessment().equals(QmsCommonConstant.NO)) - // 构建 Entry: Key是原对象,Value是排序用的数字 - .map(v -> { - String valStr = v.getValueAfter(); - BigDecimal sortVal = (valStr == null || valStr.trim().isEmpty()) - ? BigDecimal.ZERO - : new BigDecimal(valStr.trim()); - return new SimpleEntry<>(v, sortVal); - }) - // 比较 Entry 的 Value 部分 - .sorted(Map.Entry.comparingByValue()) - // 提取 Key (原对象) - .map(Map.Entry::getKey) - .collect(Collectors.toList()); - - // 获取小数精度 - int elementScale = businessAssayProjectDataDO.getDecimalPosition(); - //获取有效位数 - int effectiveDigit = businessAssayProjectDataDO.getEffectiveDigit(); - // 计算代表值(均值或差值) - BigDecimal representativeValue = calculateRepresentativeValue(sortedValues, elementScale); - - //计算后保留有效位数 - representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); - //设置判定值 - businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); - - // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(otherConfigAssayMethodProjectAssessmentDOList, representativeValue); - if (matchedRule == null) { - throw new ServiceException(1_032_100_000, "未找到超差判定区间范围,检测项目ID: " + dictionaryProjectId + ", 值: " + representativeValue); - } - - // 计算允差值 - BigDecimal allowValue; - try { - allowValue = allowanceCalculatorComponent.calculateAllowableValue(new BigDecimal(matchedRule.getMinimumValue()), new BigDecimal(matchedRule.getMaximumValue()), new BigDecimal(matchedRule.getMinimumToleraanceValue()), new BigDecimal(matchedRule.getMaximumToleraanceValue()), new BigDecimal(matchedRule.getToleraanceAdjustmentValue()), representativeValue, matchedRule.getIsUseFormula(), matchedRule.getFormula(), elementScale); - } catch (Exception e) { - throw new ServiceException(1_032_100_000, "超差判定计算出错,检测项目ID: " + dictionaryProjectId); - } - - // 判断相邻差值是否超差 - for (int i = 0; i < sortedValues.size() - 1; i++) { - BigDecimal diff = sortedValues.get(i + 1).subtract(sortedValues.get(i)).abs(); - if (diff.compareTo(allowValue) > 0) { - businessSubSampleAssessmentProjectDO.setAssessmentStatus(QmsCommonConstant.EXCEEDS_TOLERANCE); - BusinessAssayProjectDataExtendRespVO preBusinessAssayProjectDataDO = vBySortedValues.get(i); - BusinessAssayProjectDataExtendRespVO curBusinessAssayProjectDataDO = vBySortedValues.get(i + 1); - preBusinessAssayProjectDataDO.setAssessmentType(""); - curBusinessAssayProjectDataDO.setAssessmentType(""); - preBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - curBusinessAssayProjectDataDO.setIsCancelAssessment(QmsCommonConstant.NO); - //存在超差,设置为待判定 - if (!QmsCommonConstant.ASMT_PENDING_ASSESSMENT.equals(businessSubSampleAssessmentDO.getReportedStatus())) { - businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_ASSESSMENT); - } - } + // 超差:当前连续序列中断 + // 检查之前积累的组是否有效 (长度 >= 2) + if (currentGroup.size() >= 2) { + validGroups.add(new ArrayList<>(currentGroup)); // 保存副本 + } + // 重置当前组,从当前元素重新开始 + currentGroup.clear(); + currentGroup.add(curBusinessAssayProjectDataDO); + } else { + preBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); + curBusinessAssayProjectDataDO.setAssessmentType(QmsCommonConstant.ASMT_TYPE_REPRODUCIBILITY); + + // 不超差:将当前元素加入正在积累的组 + currentGroup.add(curBusinessAssayProjectDataDO); + } } + // 循环结束后,currentGroup 中可能还留有最后一段连续数据 + if (currentGroup.size() >= 2) { + validGroups.add(new ArrayList<>(currentGroup)); + } + + for (List group : validGroups) { + if (group.size() > val1.size()/2) { + sortedValues = group.stream() + .map(v -> { + String val = v.getValueAfter();//补正后的值 + return val == null || val.trim().isEmpty() ? BigDecimal.ZERO : new BigDecimal(val.trim()); + }) + .sorted() + .collect(Collectors.toList()); + + // 计算代表值(均值或差值) + representativeValue = calculateRepresentativeValue(sortedValues, elementScale); + + //计算后保留有效位数 + representativeValue = EffectiveNumberFormatter.formatNumber2(representativeValue, elementScale, effectiveDigit); + //设置判定值 + businessSubSampleAssessmentProjectDO.setAssessmentValue(representativeValue.toPlainString()); + businessSubSampleAssessmentDO.setReportedStatus(QmsCommonConstant.ASMT_PENDING_REPORT); + + //处理勾选 + List collect = group.stream().map(m -> m.getId()).collect(Collectors.toList()); + val1.forEach(item -> { + if (collect.contains(item.getId())) { + item.setIsNotAssessment(QmsCommonConstant.NO); + } else { + item.setIsNotAssessment(QmsCommonConstant.YES); + } + + }); + + break; + } + + } + } else { + throw new ServiceException(1_032_100_000, "多人,未找到再现性超差判定配置! "); } - - } } } @@ -2322,9 +1989,10 @@ public class SampleAnalysisAuditServiceImpl implements SampleAnalysisAuditServic // .eq(ConfigAssayMethodProjectAssessmentDO::getConfigAssayMethodId, businessSubSampleAssessmentProjectDO.getConfigAssayMethodId()) // .eq(ConfigAssayMethodProjectAssessmentDO::getConfigAssayMethodProjectId, businessSubSampleAssessmentProjectDO.getConfigAssayMethodProjectId())); List configAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentMapper.selectByConfigBaseSampleIdAndConfigAssayMethodIdAndConfigAssayMethodProjectId(configSubSampleMethodDO.getConfigBaseSampleId(), businessSubSampleAssessmentProjectDO.getConfigAssayMethodId(), businessSubSampleAssessmentProjectDO.getConfigAssayMethodProjectId()); + List assessmentTypeConfigAssayMethodProjectAssessmentDOList = configAssayMethodProjectAssessmentDOList.stream().filter(f -> businessAssayProjectDataDOList.get(0).getAssessmentType().equals(f.getAssessmentType())).collect(Collectors.toList()); // 查找匹配的允差规则 - ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(configAssayMethodProjectAssessmentDOList, representativeValue); + ConfigAssayMethodProjectAssessmentDO matchedRule = findMatchingRule(assessmentTypeConfigAssayMethodProjectAssessmentDOList, representativeValue); if (matchedRule == null) { throw new ServiceException(1_032_100_000, "未找到超差判定区间范围,元素ID: " + businessSubSampleAssessmentProjectDO.getDictionaryProjectId() + ", 值: " + representativeValue); } diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/service/SampleAnalysisServiceImpl.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/service/SampleAnalysisServiceImpl.java index 9561a384..697c2800 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/service/SampleAnalysisServiceImpl.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/bus/service/SampleAnalysisServiceImpl.java @@ -1073,7 +1073,7 @@ public class SampleAnalysisServiceImpl implements SampleAnalysisService { if ("withoutProject".equals(configQCSampleMethodExtendRespVO.getParentDictionaryBusinesskey())) {//不带检测项目 List businessQCCoefficientDataDOList = businessQCCoefficientDataMapper.selectByBusinessAssayTaskIdAndDictionaryBusinessKey(businessAssayTaskDO.getId(), configQCSampleMethodExtendRespVO.getDictionaryBusinessKey()); if (CollUtil.isEmpty(businessQCCoefficientDataDOList)) { - break; + continue; } BusinessQCCoefficientDataDO businessQCCoefficientDataDO = businessQCCoefficientDataDOList.get(0); @@ -1111,7 +1111,7 @@ public class SampleAnalysisServiceImpl implements SampleAnalysisService { List businessQCManagementDataDOList = businessQCManagementDataMapper.selectByBusinessAssayTaskIdAndDictionaryBusinessKey(businessAssayTaskDO.getId(), configQCSampleMethodExtendRespVO.getDictionaryBusinessKey()); if (CollUtil.isEmpty(businessQCManagementDataDOList)) { - break; + continue; } BusinessQCManagementDataDO businessQCManagementDataDO = businessQCManagementDataDOList.get(0); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentPageReqVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentPageReqVO.java index 09f63563..cd9339cb 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentPageReqVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentPageReqVO.java @@ -52,6 +52,12 @@ public class ConfigAssayMethodProjectAssessmentPageReqVO extends PageParam { @Schema(description = "允差值调整参数") private String toleraanceAdjustmentValue; + @Schema(description = "判定类型,内控超差、重复性超差、再现性超差", example = "2") + private String assessmentType; + + @Schema(description = "是否作废(取消)判定[超差时],1-是,0-否") + private Integer isCancelAssessment; + @Schema(description = "所属部门") private String systemDepartmentCode; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentRespVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentRespVO.java index 953c5a8a..8ce1bcfc 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentRespVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentRespVO.java @@ -68,6 +68,12 @@ public class ConfigAssayMethodProjectAssessmentRespVO { @ExcelProperty("允差值调整参数") private String toleraanceAdjustmentValue; + @Schema(description = "判定类型,内控超差、重复性超差、再现性超差", example = "2") + private String assessmentType; + + @Schema(description = "是否作废(取消)判定[超差时],1-是,0-否") + private Integer isCancelAssessment; + @Schema(description = "所属部门") @ExcelProperty("所属部门") private String systemDepartmentCode; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentSaveReqVO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentSaveReqVO.java index dbd35d54..6937f8e5 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentSaveReqVO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/controller/vo/ConfigAssayMethodProjectAssessmentSaveReqVO.java @@ -56,6 +56,12 @@ public class ConfigAssayMethodProjectAssessmentSaveReqVO { @Schema(description = "允差值调整参数") private String toleraanceAdjustmentValue; + @Schema(description = "判定类型,内控超差、重复性超差、再现性超差", example = "2") + private String assessmentType; + + @Schema(description = "是否作废(取消)判定[超差时],1-是,0-否") + private Integer isCancelAssessment; + @Schema(description = "所属部门") private String systemDepartmentCode; diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/dal/dataobject/ConfigAssayMethodProjectAssessmentDO.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/dal/dataobject/ConfigAssayMethodProjectAssessmentDO.java index 507a7d99..8ffe72ea 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/dal/dataobject/ConfigAssayMethodProjectAssessmentDO.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/dal/dataobject/ConfigAssayMethodProjectAssessmentDO.java @@ -97,6 +97,16 @@ public class ConfigAssayMethodProjectAssessmentDO extends BusinessBaseDO { @TableField("TLC_ADJ_VAL") private String toleraanceAdjustmentValue; /** + * 判定类型,内控超差、重复性超差、再现性超差 + */ + @TableField("ASMT_TP") + private String assessmentType; + /** + * 是否作废(取消)判定[超差时],1-是,0-否 + */ + @TableField("IS_CNL_ASMT") + private Integer isCancelAssessment; + /** * 所属部门 */ @TableField("SYS_DEPT_CD") diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/dal/mapper/ConfigAssayMethodProjectAssessmentMapper.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/dal/mapper/ConfigAssayMethodProjectAssessmentMapper.java index e0e5c543..8bda1fcb 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/dal/mapper/ConfigAssayMethodProjectAssessmentMapper.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/config/dal/mapper/ConfigAssayMethodProjectAssessmentMapper.java @@ -32,6 +32,8 @@ public interface ConfigAssayMethodProjectAssessmentMapper extends BaseMapperX