From 2761abd2f50ae9f3838d0746b9817a30cb9fc13a Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期日, 20 九月 2026 14:47:08 +0800
Subject: [PATCH] fix(汇总表): 城市客运8月/累计同比取数修正(母版删AJ辅助列+按表头定位月份列)

---
 traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java |   82 ++++++++++++++++++++++++++++++++++++++---
 1 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
index b83bd0b..50c6da6 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
@@ -226,6 +226,36 @@
                     }
                     break;
                 }
+                case "investPassengerDetail":
+                case "investLogisticsDetail": {
+                    boolean paxDetail = "investPassengerDetail".equals(t);
+                    String catName = paxDetail ? "瀹㈣繍绔欏満" : "鐗╂祦鍥尯";
+                    String catLabel = paxDetail ? "瀹㈣繍绔欏満鎶曡祫鏈堟姤" : "鐗╂祦鍥尯鎶曡祫鏈堟姤";
+                    List<InvestmentProject> catProjects = investProjectMapper.selectList(
+                        new LambdaQueryWrapper<InvestmentProject>().eq(InvestmentProject::getCategory, catName));
+                    final List<Long> catIds = new ArrayList<>();
+                    for (InvestmentProject cp : catProjects) catIds.add(cp.getId());
+                    if (catIds.isEmpty()) {
+                        rows = 0;
+                        notes.add("缂烘暟鎹細" + catLabel);
+                    } else {
+                        rows = addReadyCount(() -> investMonthlyMapper.selectCount(
+                            periodQw(period, mode, InvestmentMonthly::getReportPeriod)
+                                .in(InvestmentMonthly::getProjectId, catIds)), catLabel, notes);
+                    }
+                    String detTpl = paxDetail ? "妯℃澘_X鏈堝杩愮珯鎶曡祫鏄庣粏琛�.xlsx" : "妯℃澘_X鏈堢墿娴佺珯鍦烘姇璧勬槑缁�.xls";
+                    try {
+                        if (resolveAnyTemplate(investTemplateDir, detTpl) == null) {
+                            rows = 0;
+                            notes.add("docs/鎶曡祫/妯℃澘 涓嬬己灏戙��" + detTpl + "銆�");
+                        }
+                    } catch (Exception ex) {
+                        rows = 0;
+                        notes.add("姣嶇増瀹氫綅澶辫触锛�" + ex.getMessage());
+                    }
+                    auditTypes.add("INVEST");
+                    break;
+                }
                 default:
                     rows = 0;
                     notes.add("鏈煡鎶ヨ〃绫诲瀷锛�" + t);
@@ -381,7 +411,9 @@
                 coverage.addAll(investCover);
                 // 鎶曡祫涓哄綋鏈堟姤琛紙鏃� 1..N 绱鍙e緞锛夛紝鍙彁绀哄綋鏈堢己澶�
                 if (!investCover.contains(month)) missing.add(month);
-                investPreview(period, mode, summary, problems);
+                if ("investPassengerDetail".equals(t)) investPreview(period, mode, "瀹㈣繍绔欏満", summary, problems);
+                else if ("investLogisticsDetail".equals(t)) investPreview(period, mode, "鐗╂祦鍥尯", summary, problems);
+                else investPreview(period, mode, summary, problems);
             } else if ("energySummary".equals(t)) {
                 Long ec = energyMapper.selectCount(periodQw(period, mode, EnergyVehicleQuarterly::getReportPeriod));
                 if (ec != null && ec > 0) coverage.add(month);
@@ -412,7 +444,8 @@
     }
 
     private boolean isInvestType(String t) {
-        return "investPlan".equals(t) || "investFiveYearLogistics".equals(t) || "investBillion".equals(t) || "investCounty".equals(t);
+        return "investPlan".equals(t) || "investFiveYearLogistics".equals(t) || "investBillion".equals(t) || "investCounty".equals(t)
+            || "investPassengerDetail".equals(t) || "investLogisticsDetail".equals(t);
     }
 
     private boolean isEnergyType(String t) {
@@ -668,9 +701,23 @@
         if (allZero) problems.add("鍏ㄧ渷绱鍊煎叏涓� 0锛堝叕浜�/鍑虹鏈堟姤鍙兘鏈鍏ワ級");
     }
 
-    /** 鎶曡祫鎽樿锛氶」鐩暟 + 鏈湀瀹屾垚/鑷勾鍒�/鑷紑濮嬬疮璁� */
+    /** 鎶曡祫鎽樿锛氶」鐩暟 + 鏈湀瀹屾垚/鑷勾鍒�/鑷紑濮嬬疮璁★紙鍏ㄦ姇璧勬湀鎶ュ悎璁★紝涓嶅垎绫诲埆锛� */
     private void investPreview(String period, String mode, List<Map<String, Object>> summary, List<String> problems) {
-        List<InvestmentMonthly> list = investMonthlyMapper.selectList(periodQw(period, mode, InvestmentMonthly::getReportPeriod));
+        investPreview(period, mode, null, summary, problems);
+    }
+
+    /** 鎶曡祫鎽樿锛坈ategory 闈炵┖鏃跺彧缁熻璇ョ被鍒紝濡傚杩愮珯鍦�/鐗╂祦鍥尯鎶曡祫鏄庣粏琛級 */
+    private void investPreview(String period, String mode, String category, List<Map<String, Object>> summary, List<String> problems) {
+        LambdaQueryWrapper<InvestmentMonthly> qw = periodQw(period, mode, InvestmentMonthly::getReportPeriod);
+        if (category != null) {
+            List<InvestmentProject> ps = investProjectMapper.selectList(
+                new LambdaQueryWrapper<InvestmentProject>().eq(InvestmentProject::getCategory, category));
+            List<Long> ids = new ArrayList<>();
+            for (InvestmentProject p : ps) ids.add(p.getId());
+            if (ids.isEmpty()) { problems.add("缂烘暟鎹細搴撳唴娌℃湁銆�" + category + "銆嶉」鐩富妗�"); return; }
+            qw.in(InvestmentMonthly::getProjectId, ids);
+        }
+        List<InvestmentMonthly> list = investMonthlyMapper.selectList(qw);
         Set<Long> proj = new HashSet<>();
         double monthDone = 0.0, yearCum = 0.0, startCum = 0.0;
         for (InvestmentMonthly m : list) {
@@ -3499,13 +3546,15 @@
             int dbFilled = summaryWorkbookFiller.fillMonthlyLedger(wb, effPeriod, year, effMonth, dbProblems);
             int yoyFilled = summaryWorkbookFiller.ensureMonthYoyFormulas(wb, year, effMonth);
             int monthFormulaFilled = summaryWorkbookFiller.ensureMonthFormulas(wb, year, effMonth);
+            // 绱鍚屾瘮鍒嗘瘝淇锛氭瘝鐗堟妸銆屽幓骞村悇鏈堛�嶄笌銆屽幓骞�1-M鏈堢疮璁°�嶈緟鍔╁垪鍚屾椂璁″叆锛堥噸澶嶈/婕忓綋鏈堬級
+            int cumYoyFixed = summaryWorkbookFiller.repairCumulativeYoyFormulas(wb, year, effMonth);
             int rankRefreshed = refreshSummaryRankSheets(wb, effPeriod, "month");
             int cumulativeRefreshed = refreshSummaryCumulativeSheets(wb, year, effMonth); // 鍥涘紶璺ㄩ〉鍚堟垚椤甸殢鎶ヨ〃鏈熷埛鏂�
             int widthApplied = applySummaryReferenceLayout(wb);
             log.info("姹囨�诲伐浣滅翱鏁版嵁椹卞姩鍥炲~瀹屾垚锛氬啓鍏ュ綋鏈堝�兼牸鏁�={}锛岃ˉ鍐欏綋鏈堝悓姣斿叕寮忔牸鏁�={}锛岃ˉ鍐欏綋鏈堝悎璁″叕寮忔牸鏁�={}锛�"
-                    + "鍒锋柊鎺掑悕椤垫暟鍊兼牸鏁�={}锛屽埛鏂板洓椤碉紙鍩庡競姹囨��/鍩庡競鍒嗗競宸�/涓彛寰勫垎鏋�/閬撹矾杩愯緭鍛ㄨ浆閲忥級鏁板�兼牸鏁�={}锛�"
+                    + "淇绱鍚屾瘮鍒嗘瘝鏍兼暟={}锛屽埛鏂版帓鍚嶉〉鏁板�兼牸鏁�={}锛屽埛鏂板洓椤碉紙鍩庡競姹囨��/鍩庡競鍒嗗競宸�/涓彛寰勫垎鏋�/閬撹矾杩愯緭鍛ㄨ浆閲忥級鏁板�兼牸鏁�={}锛�"
                     + "鎸夈�婄敓鎴恄閬撹矾杩愯緭閲忔眹鎬昏〃銆嬪榻愬垪瀹藉垪鏁�={}锛岀己鏁版彁绀�={}",
-                    dbFilled, yoyFilled, monthFormulaFilled, rankRefreshed, cumulativeRefreshed, widthApplied, dbProblems);
+                    dbFilled, yoyFilled, monthFormulaFilled, cumYoyFixed, rankRefreshed, cumulativeRefreshed, widthApplied, dbProblems);
             applyTwoDecimalFormat(wb); // 鏁板�兼樉绀轰袱浣嶅皬鏁帮紙淇濈暀鍏ㄧ簿搴︼級锛�% / 鏃ユ湡绛夋棦鏈夋牱寮忎笉鏀瑰彉
             int inlineFixed = normalizeStaleInlineStrings(wb); // 娓呮帀銆岄潪 inlineStr 鍗存畫鐣� <is>銆嶇殑闈炴硶鏍硷紝鍚﹀垯 Excel 鎷掔粷鎵撳紑
             if (inlineFixed > 0) log.warn("姹囨�诲伐浣滅翱娓呮帀娈嬬暀 inlineStr 闈炴硶鏍� {} 涓紙姣嶇増鐢� openpyxl 鍐欏嚭鏃剁殑鍏稿瀷闂锛�", inlineFixed);
@@ -5381,6 +5430,7 @@
                 hssfText(row, 0, "鍚堣");
                 InvestAgg prov = new InvestAgg();
                 for (InvestmentMonthly m : monthlies) prov.add(m, pmap.get(m.getProjectId()));
+                addProjectsWithoutMonthly(prov, projects, mByProject, null, null);
                 writeInvestAggHssf(row, prov);
                 continue;
             }
@@ -5393,6 +5443,7 @@
                     InvestmentProject p = pmap.get(m.getProjectId());
                     if (p != null && blockCategory.equals(p.getCategory())) agg.add(m, p);
                 }
+                addProjectsWithoutMonthly(agg, projects, mByProject, blockCategory, null);
                 writeInvestAggHssf(row, agg);
                 seq = 0;
                 continue;
@@ -5421,6 +5472,7 @@
                     if (p != null && city.equals(p.getCity())
                         && (blockCategory == null || blockCategory.equals(p.getCategory()))) agg.add(m, p);
                 }
+                addProjectsWithoutMonthly(agg, projects, mByProject, blockCategory, city);
                 writeInvestAggHssf(row, agg);
                 continue;
             }
@@ -5468,6 +5520,24 @@
         if (agg.yearPlan > 0) hssfNum(row, 23, agg.yearCum / agg.yearPlan);
     }
 
+    /**
+     * 琛ヨ銆屾湰鏈熸病鏈夋湀搴﹁褰曘�佷絾椤圭洰涓绘。鏈夋�绘姇璧勩�嶇殑椤圭洰锛堝彧璁℃�绘姇璧勮繖涓�鍒楋級銆�
+     * 鍦烘櫙锛氭煇甯傚窞鏈湀鏈姤閫佸崟琛紙濡傛姹� 8 鏈堢墿娴侊級锛屼富妗i噷椤圭洰浠嶅湪锛岃嫢涓嶈ˉ璁★紝璇ュ競宸炲皬璁�/鍚堣浼氭暣鍧椾负绌恒��
+     *
+     * @param category 鍧楃被鍒紙瀹㈣繍绔欏満/鐗╂祦鍥尯锛夛紱null 琛ㄧず涓嶉檺
+     * @param city     甯傚窞鍏ㄧО锛堝 姝︽眽甯傦級锛沶ull 琛ㄧず涓嶉檺
+     */
+    private void addProjectsWithoutMonthly(InvestAgg agg, List<InvestmentProject> projects,
+                                           Map<Long, InvestmentMonthly> mByProject,
+                                           String category, String city) {
+        for (InvestmentProject p : projects) {
+            if (p == null || mByProject.containsKey(p.getId())) continue;
+            if (category != null && !category.equals(p.getCategory())) continue;
+            if (city != null && !city.equals(p.getCity())) continue;
+            if (p.getTotalInvestment() != null) agg.total += p.getTotalInvestment();
+        }
+    }
+
 
 
     // ==================== 鎶曡祫妯″潡锛氬杩愮珯鎶曡祫鏄庣粏琛� / 鐗╂祦绔欏満鎶曡祫鏄庣粏锛堟ā鏉垮簳绋垮師浣嶆浛鎹級 ====================

--
Gitblit v1.9.1