| | |
| | | switch (rule.getCompareType()) { |
| | | case "DIFF": |
| | | return checkDiff(rule, report, authMap); |
| | | case "DIFF_FIELDS": |
| | | return checkDiffFields(rule, report, authMap); |
| | | case "RATIO": |
| | | return checkRatio(rule, report, authMap, trackMap); |
| | | case "MOM": |
| | |
| | | return null; |
| | | } |
| | | |
| | | /** RULE_001 分项运政对比:牵引车/挂车/整车车辆数与挂车吨位/整车吨位/总吨位分别与运政对比,任一分项超限即提醒 */ |
| | | private AuditResult checkDiffFields(AuditRule rule, H2032EnterpriseMonthly report, |
| | | Map<String, TransportAuthVehicle> authMap) { |
| | | TransportAuthVehicle auth = findAuth(authMap, report.getEnterpriseName()); |
| | | if (auth == null) return null; |
| | | String[] fields = rule.getCheckField() == null ? new String[0] : rule.getCheckField().split(","); |
| | | String[] limits = rule.getThreshold() == null ? new String[0] : rule.getThreshold().split("[,;|]"); |
| | | if (fields.length == 0 || limits.length != fields.length) return null; |
| | | java.util.List<String> hits = new java.util.ArrayList<>(); |
| | | double maxAbs = 0; |
| | | for (int i = 0; i < fields.length; i++) { |
| | | String field = fields[i].trim(); |
| | | double limit; |
| | | try { |
| | | limit = Double.parseDouble(limits[i].trim()); |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | double actual; |
| | | double reference; |
| | | String unit; |
| | | switch (field) { |
| | | case "vehicleTractor": |
| | | actual = num(report.getVehicleTractor()); |
| | | reference = num(auth.getTractorCount()); |
| | | unit = "台"; |
| | | break; |
| | | case "vehicleTrailer": |
| | | actual = num(report.getVehicleTrailer()); |
| | | reference = num(auth.getTrailerCount()); |
| | | unit = "台"; |
| | | break; |
| | | case "tonsTrailer": |
| | | actual = nvl(report.getTonsTrailer()); |
| | | reference = nvl(auth.getTrailerTons()); |
| | | unit = "吨"; |
| | | break; |
| | | case "vehicleWhole": |
| | | actual = num(report.getVehicleWhole()); |
| | | reference = num(auth.getOtherCount()); |
| | | unit = "台"; |
| | | break; |
| | | case "tonsWhole": |
| | | actual = nvl(report.getTonsWhole()); |
| | | reference = nvl(auth.getOtherTons()); |
| | | unit = "吨"; |
| | | break; |
| | | case "tonsTotal": |
| | | actual = nvl(report.getTonsTotal()); |
| | | reference = nvl(auth.getTrailerTons()) + nvl(auth.getOtherTons()); |
| | | unit = "吨"; |
| | | break; |
| | | default: |
| | | return null; |
| | | } |
| | | double diff = Math.abs(actual - reference); |
| | | maxAbs = Math.max(maxAbs, diff); |
| | | if (diff > limit) { |
| | | hits.add(h2032FieldLabel(field) + ":上报=" + fmt(actual) + " " + unit + ",运政=" + fmt(reference) + " " + unit |
| | | + ",差" + fmt(diff) + " " + unit + "(限" + fmt(limit) + " " + unit + ")"); |
| | | } |
| | | } |
| | | if (hits.isEmpty()) return null; |
| | | StringBuilder detail = new StringBuilder(); |
| | | for (int i = 0; i < hits.size(); i++) { |
| | | String one = hits.get(i); |
| | | if (detail.length() == 0) { |
| | | detail.append(one); |
| | | } else if (detail.length() + one.length() + 1 <= 180) { |
| | | detail.append(";").append(one); |
| | | } else { |
| | | detail.append(";等").append(hits.size() - i).append("项超限"); |
| | | break; |
| | | } |
| | | } |
| | | return buildResult(rule, report, detail.toString(), |
| | | "牵引车/挂车/整车车辆差≤5台;挂车吨位/整车吨位差≤50吨;总吨位差≤50吨", |
| | | "超出项数=" + hits.size() + ",最大差=" + fmt(maxAbs)); |
| | | } |
| | | |
| | | /** 上报周转量与轨迹测算周转量对比,高出阈值比例核实 */ |
| | | private AuditResult checkRatio(AuditRule rule, H2032EnterpriseMonthly report, |
| | | Map<String, TransportAuthVehicle> authMap, |
| | |
| | | return null; |
| | | } |
| | | |
| | | /** 货运类型环比:本月新增(上月为0、本月>0)需核实,少的不管 */ |
| | | /** 货运类型环比(RULE_004):上月无→本月新增 或 上月有→本月无,均提醒核实 */ |
| | | private AuditResult checkMom(AuditRule rule, H2032EnterpriseMonthly report, |
| | | Map<String, H2032EnterpriseMonthly> lastMonthMap) { |
| | | H2032EnterpriseMonthly lastMonth = lastMonthMap.get(key(report.getEnterpriseCode())); |
| | | if (lastMonth == null) return null; |
| | | List<String> hits = new ArrayList<>(); |
| | | List<String> addHits = new ArrayList<>(); |
| | | List<String> delHits = new ArrayList<>(); |
| | | for (String field : rule.getCheckField().split(",")) { |
| | | double current = getH2032FieldValue(report, field); |
| | | double last = getH2032FieldValue(lastMonth, field); |
| | | if (current > 0 && last == 0) { |
| | | hits.add(h2032FieldLabel(field) + "=" + fmt(current)); |
| | | addHits.add(h2032FieldLabel(field) + "=" + fmt(current)); |
| | | } else if (last > 0 && current == 0) { |
| | | delHits.add(h2032FieldLabel(field) + "(上月=" + fmt(last) + ",本月无)"); |
| | | } |
| | | } |
| | | if (!hits.isEmpty()) { |
| | | return buildResult(rule, report, "本月新增: " + String.join("、", hits), |
| | | "上月该类型为0", "本月新增货运类型(上月无)"); |
| | | if (!addHits.isEmpty() || !delHits.isEmpty()) { |
| | | StringBuilder msg = new StringBuilder(); |
| | | if (!addHits.isEmpty()) msg.append("本月新增: ").append(String.join("、", addHits)); |
| | | if (!delHits.isEmpty()) { |
| | | if (msg.length() > 0) msg.append(";"); |
| | | msg.append("本月消失: ").append(String.join("、", delHits)); |
| | | } |
| | | return buildResult(rule, report, msg.toString(), |
| | | "上月无→本月新增 或 上月有→本月无", "货运类型环比新增/消失需核实"); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** 有货运量但对应车辆为0 需核实(如 有集装箱货运量无集装箱车辆) */ |
| | | private AuditResult checkNull(AuditRule rule, H2032EnterpriseMonthly report) { |
| | | String[] fields = rule.getCheckField().split(","); |
| | |
| | | labels.put("tonsWhole", "整车吨位"); |
| | | labels.put("turnoverTotal", "周转量"); |
| | | labels.put("vehicleWhole", "整车车辆数"); |
| | | labels.put("vehicleTractor", "牵引车数"); |
| | | labels.put("vehicleTrailer", "挂车数"); |
| | | labels.put("tonsTrailer", "挂车吨位"); |
| | | labels.put("tonsWhole", "整车吨位"); |
| | | String v = labels.get(field); |
| | | return v == null ? field : v; |
| | | } |