From 520bdcba17d90b07d7d63fdcdb0e98a2a0a87300 Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期六, 03 十月 2026 19:30:25 +0800
Subject: [PATCH] fix(holiday): 快报表格改用带符号百分比并保留模板样式

---
 HANDOFF.md                                                                                          |    7 +++++++
 traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java |   31 +++++++++++++++++++++++++++++++
 traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java     |   11 ++++++++++-
 3 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/HANDOFF.md b/HANDOFF.md
index c6dff64..8ab0814 100644
--- a/HANDOFF.md
+++ b/HANDOFF.md
@@ -16,6 +16,13 @@
 - **楠岃瘉锛堟湰鏈� 3305 搴� + 鐪熷疄妯℃澘锛�**锛氭帴鍙e鍏ョ粨鏋� `passengerRows=10, vehicleRows=4, successRows=14, failRows=0`锛涙暟鎹簱鎶芥煡 2026-09-30 閾佽矾=82.1銆佹皯鑸�=6.6994锛�2026-10-01 閾佽矾=113.8銆佹皯鑸�=6.7482銆侀亾璺�=78.82銆佹按璺�=1.311锛�2026-10-02 閾佽矾=82.0銆佹皯鑸�=6.3914銆侀亾璺�=75.61銆佹按璺�=3.3373锛�2026-10-01 蹇姤閾佽矾鐜瘮=+38.6%銆佹皯鑸幆姣�=+0.7%锛屾�昏鐜瘮涓衡�溾�斺�濓紱2026-10-02 閾佽矾鐜瘮=-27.9%銆佹皯鑸幆姣�=-5.3%銆�
 - **杩愯鐘舵��**锛氬悗绔� 8090锛堥噸鍚悗宸插姞杞芥柊浠g爜锛夈�佸墠绔� 8080 鍧囧湪杩愯锛涜闂� `http://localhost:8080`銆�
 
+### 10-03 娣卞锛氬揩鎶ヨ〃鏍肩櫨鍒嗘瘮涓庢ā鏉挎牱寮忎慨澶嶏紙宸查獙鏀讹級
+- **闂**锛氱敓鎴愬揩鎶ヨ〃鏍间娇鐢ㄢ�滃闀�/涓嬮檷鈥濇枃瀛楋紝鏁板瓧鎷嗚骞跺鍑� 1 椤碉紱澶嶆牳鍙戠幇妯℃澘璺緞姝g‘锛屾牴鍥犳槸 `HolidayBulletinService#setCellText` 鏇挎崲鍗曞厓鏍兼椂鍙繚鐣欐钀藉睘鎬э紝鏈繚鐣欐ā鏉� run 鐨勫瓧浣�/瀛楀彿灞炴�с��
+- **鍙e緞**锛氳〃鏍肩幆姣�/鍚屾瘮鏀逛负甯︾鍙蜂竴浣嶅皬鏁帮紙姝f暟涓嶅姞 `+`锛岃礋鏁颁繚鐣� `-`锛夛紝闆舵垨涓�浣嶅皬鏁板悗涓洪浂鏄剧ず `0%`锛岀己澶�/鍩烘暟涓虹┖鎴栦负闆舵樉绀� `鈥擿锛涙鏂囩户缁娇鐢ㄢ�滃闀�/涓嬮檷鈥濄��
+- **淇**锛氬崟鍏冩牸鏇挎崲鏃剁户鎵挎ā鏉� `rPr`锛涙柊澧� `HolidayBulletinServiceTest` 瑕嗙洊姝f暟銆佽礋鏁般�侀浂銆佸洓鑸嶄簲鍏ヤ负闆躲�佺己澶卞拰闆跺熀鏁般��
+- **楠岃瘉**锛歁aven 缂栬瘧鍜屾祴璇曢�氳繃锛涢噸鏂扮敓鎴� 2026-10-01 蹇姤锛屾鏂囦粛涓衡�滃闀�2.3%鈥濅笖涓嶅惈鈥滃闀夸簡鈥濓紱Word 瀵煎嚭鐢� 2 椤垫仮澶嶄负 1 椤碉紝鏁板瓧涓嶅啀鎷嗚銆傛渶缁堟牱鎶ヨ鏈湴 `_tmp_holiday_verify/bulletin_final_signed_styled_2026-10-01.docx`銆�
+- **鐘舵��**锛�2026-10-03 鐢ㄦ埛楠屾敹閫氳繃锛涙湰娆℃彁浜ゅ彧鍖呭惈浠g爜銆佸洖褰掓祴璇曞拰鏈氦鎺ヨ褰曪紝涓嶅寘鍚� `_tmp_*` 杩囩▼浜х墿鍙婄敤鎴锋湭鎻愪氦鐨勬暟鎹枃浠堕噸鍛藉悕銆�
+
 ---
 
 ### 琛ュ厖锛�10-03 涓嬪崍锛夛細鏈嶅姟鍣ㄩ儴缃叉姤 鈥淎ccess denied ... (using password: NO)鈥� 鈥斺�� 鏍瑰洜涓庝慨澶�
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java
index e6ef8ac..1ef5884 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java
@@ -24,6 +24,7 @@
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.nio.file.Files;
 import java.time.LocalDate;
 import java.util.ArrayList;
@@ -250,7 +251,10 @@
             Element pPr = firstChildElement(templateParagraph, "pPr");
             if (pPr != null) paragraph.appendChild(pPr.cloneNode(true));
         }
+        Element templateRun = templateParagraph == null ? null : firstChildElement(templateParagraph, "r");
+        Element rPr = templateRun == null ? null : firstChildElement(templateRun, "rPr");
         Element run = createElement("r");
+        if (rPr != null) run.appendChild(rPr.cloneNode(true));
         Element t = createElement("t");
         t.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve");
         t.setTextContent(text == null ? "" : text);
@@ -330,7 +334,12 @@
 
     private String ratio(BigDecimal current, BigDecimal base) {
         if (current == null || base == null || base.abs().compareTo(EPSILON) < 0) return "鈥�";
-        return ratioPhrase(current, base);
+        BigDecimal ratio = HolidayNumberUtils.divide(current, base);
+        if (ratio == null) return "鈥�";
+        BigDecimal percent = HolidayNumberUtils.multiply(ratio.subtract(BigDecimal.ONE), BigDecimal.valueOf(100));
+        if (percent == null) return "鈥�";
+        BigDecimal rounded = percent.setScale(1, RoundingMode.HALF_UP);
+        return rounded.signum() == 0 ? "0%" : rounded.toPlainString() + "%";
     }
 
     private String number(BigDecimal value) {
diff --git a/traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java b/traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java
new file mode 100644
index 0000000..4830de8
--- /dev/null
+++ b/traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java
@@ -0,0 +1,31 @@
+package com.trafficaudit.holiday.service;
+
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class HolidayBulletinServiceTest {
+
+    @Test
+    void formatsTableRatiosAsSignedPercentages() throws Exception {
+        HolidayBulletinService service = new HolidayBulletinService(null);
+
+        assertEquals("-4.7%", ratio(service, "95.3", "100"));
+        assertEquals("1.0%", ratio(service, "101", "100"));
+        assertEquals("0%", ratio(service, "100", "100"));
+        assertEquals("0%", ratio(service, "10004", "10000"));
+        assertEquals("鈥�", ratio(service, "100", null));
+        assertEquals("鈥�", ratio(service, "100", "0"));
+    }
+
+    private String ratio(HolidayBulletinService service, String current, String base) throws Exception {
+        Method method = HolidayBulletinService.class.getDeclaredMethod("ratio", BigDecimal.class, BigDecimal.class);
+        method.setAccessible(true);
+        BigDecimal currentValue = current == null ? null : new BigDecimal(current);
+        BigDecimal baseValue = base == null ? null : new BigDecimal(base);
+        return (String) method.invoke(service, currentValue, baseValue);
+    }
+}

--
Gitblit v1.9.1