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/rulemanage/controller/RuleManageController.java |  107 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 93 insertions(+), 14 deletions(-)

diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/rulemanage/controller/RuleManageController.java b/traffic-audit-server/src/main/java/com/trafficaudit/rulemanage/controller/RuleManageController.java
index b55fea1..a3dbab1 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/rulemanage/controller/RuleManageController.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/rulemanage/controller/RuleManageController.java
@@ -55,29 +55,108 @@
         if (body.getThreshold() != null) rule.setThreshold(body.getThreshold());
         if (body.getAlertLevel() != null) rule.setAlertLevel(body.getAlertLevel());
         if (body.getDescription() != null) rule.setDescription(body.getDescription());
-        // 闃堝�煎彉鍖栨椂鍚屾瑙勫垯鍚嶇О涓庤鏄庯紙鍚嶇О/璇存槑閲岀殑 卤N% 鎸夋柊闃堝�兼敼鍐欙級锛屽苟闅忎繚瀛樻寔涔呭寲
+        // 闃堝�煎彉鍖栨椂鍚屾瑙勫垯鍚嶇О涓庤鏄庯紙鍚嶇О/璇存槑閲屼笌鏃ч槇鍊煎搴旂殑 N% 鐗囨鎸夋柊闃堝�兼敼鍐欙級锛屽苟闅忎繚瀛樻寔涔呭寲
         if (body.getThreshold() != null && !body.getThreshold().equals(oldThreshold)) {
-            syncThresholdText(rule);
+            syncThresholdText(rule, oldThreshold);
         }
         rule.setUpdatedAt(LocalDateTime.now());
         ruleMapper.updateById(rule);
         return Result.ok("宸蹭繚瀛�");
     }
 
-    /** 卤N% 瀛楁牱鍖归厤锛堝悕绉�/璇存槑涓殢闃堝�煎姩鎬佸彉鍖栫殑鐗囨锛� */
-    private static final Pattern PCT_TOKEN = Pattern.compile("卤\\s*\\d+(?:\\.\\d+)?\\s*%");
+    /** 鍚嶇О/璇存槑涓殢闃堝�煎姩鎬佸彉鍖栫殑鏁板瓧鐗囨锛氬尮閰嶄换鎰忔暟瀛楋紙% 鍓嶅悗銆佸彴/鍚�/鍏噷绛夊崟浣嶅墠鍧囧彲锛� */
+    private static final Pattern NUM_TOKEN = Pattern.compile("\\d+(?:\\.\\d+)?");
 
-    /** 鎶婃枃鏈腑鐨� 卤N% 鏇挎崲涓� 卤threshold%锛堝惈宸插甫 卤 鐨勫墠缂�锛岄伩鍏嶅弻 卤锛� */
-    private String decorateThresholdText(String text, String threshold) {
-        if (text == null || text.trim().isEmpty() || threshold == null || threshold.trim().isEmpty()) return text;
-        String token = "卤" + threshold.trim() + "%";
-        return PCT_TOKEN.matcher(text).replaceAll(Matcher.quoteReplacement(token));
+    /** 瑙f瀽闃堝�煎瓧绗︿覆涓殑鎵�鏈夋暟鍊硷紙鏀寔鈥�5,5,50鈥濈瓑澶氭闃堝�硷紝濡� RULE_001 鍒嗛」杩愭斂瀵规瘮锛� */
+    private java.util.List<Double> parseThresholdNums(String threshold) {
+        java.util.List<Double> out = new java.util.ArrayList<>();
+        if (threshold == null || threshold.trim().isEmpty()) return out;
+        java.util.regex.Matcher m = NUM_TOKEN.matcher(threshold.trim());
+        while (m.find()) {
+            try {
+                out.add(Double.parseDouble(m.group()));
+            } catch (Exception e) {
+                // 蹇界暐鏃犳硶瑙f瀽鐨勬
+            }
+        }
+        return out;
     }
 
-    /** 鍚嶇О/璇存槑闅忛槇鍊煎悓姝ワ紙璇诲垪琛ㄦ椂涔熷姩鎬佹牎姝o紝DB 涓棫鏂囨湰涓嶉樆濉炴樉绀猴級 */
-    private void syncThresholdText(AuditRule rule) {
+    /** 鏁板�煎睍绀猴細鏁存暟鍘绘帀灏忔暟浣嶏紝鍏朵綑淇濈暀鍘熺簿搴� */
+    private String fmtNum(double v) {
+        long l = Math.round(v);
+        if (Math.abs(v - l) < 1e-9) return Long.toString(l);
+        return new java.math.BigDecimal(String.valueOf(v)).stripTrailingZeros().toPlainString();
+    }
+
+    /** 鐢遍槇鍊兼暟鍊兼帹瀵尖�滃悕绉�/璇存槑閲屽啓鐨勬槸鐧惧垎涔嬪嚑鈥濈殑鍊欓�夊彛寰勶細
+     *  鈶� 闃堝�兼湰韬氨鏄櫨鍒嗘暟锛堝 20 鈫� 卤20%锛夛紱
+     *  鈶� 闃堝�兼槸灏忔暟姣斾緥锛堝 0.02 鈫� 2%銆�0.5 鈫� 50%锛夛紱姝ゆ椂 <1 鎵嶅惎鐢紱
+     *  鈶� 闃堝�兼槸姣斿�硷紙濡� 1.3 鈫� 楂樺嚭30%锛夛紱姝ゆ椂 >1 鎵嶅惎鐢紱
+     *  鍏朵綑鎸夊師鏁板尮閰嶏紙鍙�/鍚�/鍏噷绛夐槇鍊煎師鏍峰嚭鐜板湪鏂囧瓧涓級銆� */
+    private double[] thresholdPercentCandidates(double v) {
+        double[] cands;
+        if (v > 0 && v < 1) {
+            cands = new double[]{v, v * 100};
+        } else if (v > 1) {
+            cands = new double[]{v, (v - 1) * 100};
+        } else {
+            cands = new double[]{v};
+        }
+        return cands;
+    }
+
+    /** 鎸夆�滄棫闃堝�尖啋鏂伴槇鍊尖�濋�愭鏀瑰啓鍚嶇О/璇存槑涓殑鏁板瓧锛�
+     *  鍙浛鎹笌鏃ч槇鍊兼煇涓�娈碉紙鎴栧叾鐧惧垎姣斿彛寰勶級瀵瑰緱涓婄殑鏁板瓧锛涘娈甸槇鍊硷紙閫楀彿鍒嗛殧锛夐�愭瀵瑰簲锛�
+     *  涓庨槇鍊兼棤鍏崇殑鏁板瓧锛堟棩鏈熴�佷笌瑙勫垯鏃犲叧鐨勫浐瀹氭暟鍊肩瓑锛変繚鎸佷笉鍔ㄣ�� */
+    private String decorateThresholdText(String text, String oldThreshold, String newThreshold) {
+        if (text == null || text.trim().isEmpty()) return text;
+        java.util.List<Double> olds = parseThresholdNums(oldThreshold);
+        java.util.List<Double> news = parseThresholdNums(newThreshold);
+        if (olds.isEmpty() || olds.size() != news.size()) return text;
+        int n = olds.size();
+        double[][] oc = new double[n][];
+        double[][] nc = new double[n][];
+        for (int i = 0; i < n; i++) {
+            oc[i] = thresholdPercentCandidates(olds.get(i));
+            nc[i] = thresholdPercentCandidates(news.get(i));
+            if (oc[i].length != nc[i].length) return text;
+        }
+        java.util.regex.Matcher m = NUM_TOKEN.matcher(text);
+        StringBuffer sb = new StringBuffer();
+        while (m.find()) {
+            double token;
+            try {
+                token = Double.parseDouble(m.group());
+            } catch (Exception e) {
+                continue;
+            }
+            String repl = null;
+            outer:
+            for (int i = 0; i < n; i++) {
+                for (int j = 0; j < oc[i].length; j++) {
+                    if (Math.abs(oc[i][j] - token) < 1e-9) {
+                        repl = fmtNum(nc[i][j]);
+                        break outer;
+                    }
+                }
+            }
+            if (repl == null) continue;
+            m.appendReplacement(sb, Matcher.quoteReplacement(repl));
+        }
+        m.appendTail(sb);
+        return sb.toString();
+    }
+
+    /** 鍚嶇О/璇存槑闅忛槇鍊煎悓姝ワ紙update 鏃舵寜 鏃р啋鏂� 鏀瑰啓骞舵寔涔呭寲锛涘娈甸槇鍊煎悓鏍烽�愭鑱斿姩锛� */
+    private void syncThresholdText(AuditRule rule, String oldThreshold) {
         if (rule == null || rule.getThreshold() == null) return;
-        rule.setRuleName(decorateThresholdText(rule.getRuleName(), rule.getThreshold()));
-        rule.setDescription(decorateThresholdText(rule.getDescription(), rule.getThreshold()));
+        rule.setRuleName(decorateThresholdText(rule.getRuleName(), oldThreshold, rule.getThreshold()));
+        rule.setDescription(decorateThresholdText(rule.getDescription(), oldThreshold, rule.getThreshold()));
     }
-}
\ No newline at end of file
+
+    /** 璇诲垪琛ㄦ椂鑷剤锛氫粎褰撴枃鏈墖娈典笌褰撳墠闃堝�煎搴旀椂鎵嶆敼鍐欙紙骞傜瓑锛屼笉璇激涓庨槇鍊兼棤鍏崇殑鏁板瓧锛� */
+    private void syncThresholdText(AuditRule rule) {
+        syncThresholdText(rule, rule == null ? null : rule.getThreshold());
+    }
+}

--
Gitblit v1.9.1