From 5e2982df8aca712c3156711c1917fcedb6cfb087 Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期三, 09 九月 2026 10:30:23 +0800
Subject: [PATCH] fix: 09-09上午整改——RULE_001分项运政对比(6段)+阈值说明联动通用化+汇总大表列宽回归母版+导入结果弹窗 + 测试报告与工作日结

---
 traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java b/traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java
index 5d343bb..8269c27 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/auditengine/service/AuditEngineService.java
@@ -1569,6 +1569,8 @@
             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":
@@ -1611,6 +1613,86 @@
         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,
@@ -1645,26 +1727,34 @@
         return null;
     }
 
-    /** 璐ц繍绫诲瀷鐜瘮锛氭湰鏈堟柊澧烇紙涓婃湀涓�0銆佹湰鏈�>0锛夐渶鏍稿疄锛屽皯鐨勪笉绠� */
+    /** 璐ц繍绫诲瀷鐜瘮锛圧ULE_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(",");
@@ -1796,6 +1886,10 @@
         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;
     }

--
Gitblit v1.9.1