Browse Source

Merge remote-tracking branch 'origin/feature/agg' into feature/agg

feature/agg
yinhuaiwei 10 hours ago
parent
commit
237ab9e8df
1 changed files with 400 additions and 0 deletions
  1. +400
    -0
      inspect-main/inspect-main-task/src/main/java/com/inspect/analysis/utils/ResultAnalysisUtils.java

+ 400
- 0
inspect-main/inspect-main-task/src/main/java/com/inspect/analysis/utils/ResultAnalysisUtils.java View File

@ -472,6 +472,406 @@ public class ResultAnalysisUtils {
log.info("------------------parseAlg resultAnalysis: {}", resultAnalysis);
}
/**
* parseAlg 的重构版本,保留原方法用于对比。
*
* 与 parseAlg 相比主要修复:
* 1. 原始值与 formatValue 后的值分开保存,表计类按逗号拆分后逐个判断,避免只取第一个值;
* 2. gis_meter 也纳入读数失败判断;
* 3. 修复 value == "null" 的引用比较;
* 4. correction 不再在方法末尾强制 resultType=1;
* 5. 状态赋值统一收敛到 markNormal/markDefect/markAbnormal。
*
* 注意:本方法暂未替换调用方,便于与 parseAlg 并行对比。
*/
public void parseAlg2(String algType, AlgValue algValue, String value, String defaultDesc, ResultAnalysis resultAnalysis) {
log.info("PARSE_ALG2 algType: {}, algValue: {}, value: {}, defaultDesc: {}", algType, algValue, value, defaultDesc);
// 初筛红外:非 infrared 的红外算法在初筛阶段直接按正常展示
if ("1".equals(resultAnalysis.getFilter())
&& !AlgConstants.INFRARED.equals(algType)
&& AlgConstants.ALG_INFRARED_LIST.contains(algType)) {
markNormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
resultAnalysis.setResValue("--");
resultAnalysis.setDescription("-");
resultAnalysis.setCreateTime(new Date());
return;
}
String rawValue = value == null ? "" : value.trim();
AlgValue safeAlgValue = algValue == null ? new AlgValue() : algValue;
String formattedValue = safeAlgValue.formatValue(rawValue);
formattedValue = formattedValue == null ? "" : formattedValue.trim();
// filter=1 时,非红外算法不再进入具体算法分支(对应原逻辑 algType="")
boolean skipAlgorithm = "1".equals(resultAnalysis.getFilter())
&& !AlgConstants.INFRARED.equals(algType);
String effectiveAlgType = skipAlgorithm ? "" : algType;
if (effectiveAlgType == null) {
log.warn("parseAlg2 algType is null!");
return;
}
boolean meterLike = AlgConstants.METER.equals(effectiveAlgType)
|| AlgConstants.GIS_METER.equals(effectiveAlgType);
// 表计类自己处理空值和多值,其余算法沿用原来的空值哨兵
if (!meterLike && isReadFailureValue(formattedValue)) {
applyEmptyResult(effectiveAlgType, resultAnalysis);
return;
}
String desc;
if (skipAlgorithm) {
desc = parseDefault(formattedValue, defaultDesc, resultAnalysis);
} else if (meterLike) {
desc = parseMeterOrGisMeter(effectiveAlgType, safeAlgValue, rawValue, defaultDesc, resultAnalysis);
} else if ("qrcode".equals(effectiveAlgType) || "light".equals(effectiveAlgType)) {
markNormal(resultAnalysis, ResStatusEnum.CONFIRM.getCode());
desc = defaultDesc;
} else if ("switch".equals(effectiveAlgType)) {
desc = parseSwitch(rawValue, resultAnalysis);
} else if (AlgConstants.GIS_METER_2.equals(effectiveAlgType)) {
desc = parseGisMeter2(safeAlgValue, rawValue, resultAnalysis);
} else if ("sound".equals(effectiveAlgType)) {
desc = parseSound(formattedValue, resultAnalysis);
} else if (AlgConstants.ALG_INFRARED_LIST.contains(effectiveAlgType)
|| "xb".equals(effectiveAlgType)) {
desc = parseInfrared(safeAlgValue, formattedValue, resultAnalysis);
} else if ("isolator".equals(effectiveAlgType)) {
desc = parseIsolator(formattedValue, resultAnalysis);
} else if (AlgConstants.CORRECTION.equals(effectiveAlgType)) {
desc = parseCorrection(rawValue, resultAnalysis);
} else {
desc = parseDefault(formattedValue, defaultDesc, resultAnalysis);
}
resultAnalysis.setDescription(desc);
resultAnalysis.setCreateTime(new Date());
log.info("------------------parseAlg2 resultAnalysis: {}", resultAnalysis);
}
private boolean isReadFailureValue(String value) {
return StringUtils.isEmpty(value) || "-1".equals(value) || "null".equals(value);
}
private void applyEmptyResult(String algType, ResultAnalysis resultAnalysis) {
log.info("PARSE_ALG2_EMPTY algType: {}", algType);
String desc;
if (AlgConstants.METER.equals(algType) || AlgConstants.GIS_METER.equals(algType)) {
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
desc = "读数失败";
} else {
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
desc = AlgConstants.INFRARED.equals(algType) ? "读数失败" : "算法内部异常";
}
resultAnalysis.setResValue("--");
resultAnalysis.setDescription(desc);
resultAnalysis.setCreateTime(new Date());
}
private void markNormal(ResultAnalysis resultAnalysis, String resStatus) {
markResult(resultAnalysis, PointStatusEnum.NORMAL.getCode(),
ResultTypeEnum.NORMAL.getCode(), resStatus);
}
private void markDefect(ResultAnalysis resultAnalysis, String resStatus) {
markResult(resultAnalysis, PointStatusEnum.DEFECT.getCode(),
ResultTypeEnum.DEFECT.getCode(), resStatus);
}
private void markAbnormal(ResultAnalysis resultAnalysis, String resStatus) {
markResult(resultAnalysis, PointStatusEnum.ABNORMAL.getCode(),
ResultTypeEnum.ABNORMAL.getCode(), resStatus);
}
private void markResult(ResultAnalysis resultAnalysis, String pointStatus,
String resultType, String resStatus) {
resultAnalysis.setPointStatus(pointStatus);
resultAnalysis.setResultType(resultType);
resultAnalysis.setResStatus(resStatus);
}
private String parseMeterOrGisMeter(String algType, AlgValue algValue, String rawValue,
String defaultDesc, ResultAnalysis resultAnalysis) {
String[] rawValues = rawValue.split(StringUtils.COMMA, -1);
List<String> descs = new ArrayList<>(rawValues.length);
boolean hasDefect = false;
boolean hasAbnormal = false;
boolean evaluatedNumeric = false;
for (String rawItem : rawValues) {
String item = rawItem == null ? "" : rawItem.trim();
String formatted = algValue.formatValue(item);
formatted = formatted == null ? "" : formatted.trim();
if (isMeterReadFailure(algType, item, formatted)) {
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
if (StringUtils.isEmpty(rawValue) || "null".equals(rawValue) || "-1".equals(rawValue)) {
resultAnalysis.setResValue("--");
}
return "读数失败";
}
if (isNormalToken(formatted)) {
descs.add("正常");
continue;
}
evaluatedNumeric = true;
AlgAlarmResult alarmResult = algValue.analyze(formatted);
if (!alarmResult.isAlarm()) {
descs.add("正常");
} else if (AlgAlarmResult.Status.PARSE_ERROR == alarmResult.getStatus()) {
hasAbnormal = true;
descs.add("异常");
} else {
hasDefect = true;
descs.add("表计超限" + alarmResult.messageSuffix());
}
}
if (hasDefect) {
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return joinDescriptions(descs);
}
if (hasAbnormal) {
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return joinDescriptions(descs);
}
markNormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
if (evaluatedNumeric && StringUtils.isNotEmpty(defaultDesc) && defaultDesc.contains("失败")) {
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return defaultDesc;
}
return "正常";
}
private boolean isMeterReadFailure(String algType, String rawItem, String formatted) {
if (StringUtils.isEmpty(rawItem) || "null".equals(rawItem) || "null".equals(formatted)) {
return true;
}
if ("-1".equals(rawItem) || "-1".equals(formatted)) {
return true;
}
return AlgConstants.GIS_METER.equals(algType) && "10003".equals(formatted);
}
private boolean isNormalToken(String formatted) {
if ("open".equalsIgnoreCase(formatted)
|| "closed".equalsIgnoreCase(formatted)
|| "off".equalsIgnoreCase(formatted)
|| "on".equalsIgnoreCase(formatted)
|| "正常".equals(formatted)) {
return true;
}
return formatted.contains("分OFF") || formatted.contains("分") || formatted.contains("合");
}
private String joinDescriptions(List<String> descs) {
if (descs.isEmpty()) {
return "正常";
}
if (descs.size() == 1) {
return descs.get(0);
}
return String.join(",", descs);
}
private String parseSwitch(String rawValue, ResultAnalysis resultAnalysis) {
String[] values = rawValue.split(StringUtils.COMMA, -1);
boolean isDefect = false;
boolean isAbnormal = false;
for (String value : values) {
String item = value == null ? "" : value.trim();
if ("灭".equals(item)) {
isDefect = true;
}
if (StringUtils.isEmpty(item) || "null".equals(item)
|| "1".equals(item) || "未识别".equals(item)) {
isAbnormal = true;
}
}
if (isDefect) {
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
} else if (isAbnormal) {
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
} else {
markNormal(resultAnalysis, ResStatusEnum.CONFIRM.getCode());
}
return rawValue;
}
private String parseGisMeter2(AlgValue algValue, String rawValue, ResultAnalysis resultAnalysis) {
log.info("parseAlg2 gis_meter2 value: {}, resCode: {}", rawValue, resultAnalysis.getResCode());
boolean hasDefect = false;
boolean hasReadFailure = false;
try {
String[] values = JSON.parseArray(rawValue, String.class).toArray(new String[0]);
String[] descs = new String[values.length];
for (int i = 0; i < values.length; i++) {
String item = values[i];
if (StringUtils.isEmpty(item)) {
hasReadFailure = true;
values[i] = "--";
descs[i] = "读数失败";
} else {
AlgAlarmResult itemAlarm = algValue.analyze(item);
if (itemAlarm.isAlarm()) {
hasDefect = true;
descs[i] = "表计超限" + itemAlarm.messageSuffix();
} else {
descs[i] = "正常";
}
}
}
String valueStr = String.join(",", values);
String descStr = String.join(",", descs);
resultAnalysis.setResValue(valueStr);
// 无人机表计所有读数失败都按缺陷处理
if (hasDefect || hasReadFailure) {
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
} else {
markNormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
}
return descStr;
} catch (Exception e) {
log.error("parseAlg2 gis_meter2 parse error, value: {}", rawValue, e);
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "解析异常";
}
}
private String parseSound(String value, ResultAnalysis resultAnalysis) {
if ("1".equals(value)) {
markNormal(resultAnalysis, ResStatusEnum.CONFIRM.getCode());
return "正常";
}
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "异常";
}
private String parseInfrared(AlgValue algValue, String value, ResultAnalysis resultAnalysis) {
AlgAlarmResult alarmResult = algValue.analyze(value);
if (!alarmResult.isAlarm()) {
markNormal(resultAnalysis, ResStatusEnum.CONFIRM.getCode());
return "正常";
}
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "温度异常告警" + alarmResult.messageSuffix();
}
private String parseIsolator(String value, ResultAnalysis resultAnalysis) {
String desc;
if ("1".equals(value)) {
markNormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
desc = "分";
} else if ("2".equals(value)) {
markNormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
desc = "合";
} else if ("3".equals(value)) {
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
desc = "分位异常";
} else if ("4".equals(value)) {
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
desc = "合位异常";
} else {
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
desc = "未检测到刀闸";
}
resultAnalysis.setResValue(desc);
return desc;
}
private String parseCorrection(String rawValue, ResultAnalysis resultAnalysis) {
String resCode = resultAnalysis.getResCode();
log.info("parseAlg2 correction resCode: {}, value: {}", resCode, rawValue);
if ("2000".equals(resCode)) {
List<List<Double>> list = readCorrectionMatrix(rawValue);
if (isValidCorrectionMatrix(list)) {
markNormal(resultAnalysis, ResStatusEnum.CANCEL.getCode());
resultAnalysis.setResValue("");
return "无需纠偏";
}
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "纠偏结果异常";
}
if ("2001".equals(resCode)) {
List<List<Double>> list = readCorrectionMatrix(rawValue);
if (isValidCorrectionMatrix(list)) {
if (isAllZero(list)) {
markNormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "纠偏码异常";
}
markDefect(resultAnalysis, ResStatusEnum.CORRECT.getCode());
return "纠偏码异常请进行纠偏";
}
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "纠偏码和值均异常";
}
if ("2002".equals(resCode)) {
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "超出比对范围";
}
if ("2003".equals(resCode)) {
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "图像数据错误";
}
markAbnormal(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
return "未知异常";
}
private List<List<Double>> readCorrectionMatrix(String rawValue) {
ObjectMapper mapper = new ObjectMapper();
try {
log.info("parseAlg2 correction value: {}", rawValue);
List<List<Double>> list = mapper.readValue(rawValue, new TypeReference<List<List<Double>>>() {
});
log.info("parseAlg2 correction parsed: {}", list);
return list;
} catch (Exception e) {
log.error("parseAlg2 correction parse error, value: {}", rawValue, e);
return new ArrayList<>();
}
}
private boolean isValidCorrectionMatrix(List<List<Double>> list) {
return list != null
&& list.size() == 2
&& list.get(0) != null && list.get(0).size() == 2
&& list.get(1) != null && list.get(1).size() == 2;
}
private boolean isAllZero(List<List<Double>> list) {
final double epsilon = 1e-8;
for (List<Double> row : list) {
for (Double value : row) {
if (value != null && Math.abs(value) >= epsilon) {
return false;
}
}
}
return true;
}
private String parseDefault(String value, String defaultDesc, ResultAnalysis resultAnalysis) {
String desc = defaultDesc;
if ("0".equals(value)) {
markNormal(resultAnalysis, ResStatusEnum.CANCEL.getCode());
desc = "正常";
resultAnalysis.setSuggestion("系统审核");
} else if ("1".equals(value)) {
markDefect(resultAnalysis, ResStatusEnum.UNCONFIRM.getCode());
}
if (StringUtils.isNotEmpty(desc) && desc.contains("分析失败")) {
resultAnalysis.setPointStatus(PointStatusEnum.ABNORMAL.getCode());
resultAnalysis.setResultType(ResultTypeEnum.ABNORMAL.getCode());
}
return desc;
}
/**
* 将分析结果的辅助值进行合并展示
*


Loading…
Cancel
Save