From 799ec6799ad9e994f7d369f059ca7682962f648f Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期三, 02 九月 2026 00:08:30 +0800
Subject: [PATCH] fix: 能耗导入同报表期并发重导互斥锁 + 空车牌(0)过滤 + 前端导入按钮防连点

---
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java |  154 ++++++++++++++++++++++++++++-----------------------
 1 files changed, 84 insertions(+), 70 deletions(-)

diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java
index 04b7e2e..41b922c 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java
@@ -67,6 +67,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import com.trafficaudit.dataimport.dto.ImportResult;
 import org.apache.poi.ss.usermodel.DateUtil;
 import java.util.Comparator;
@@ -94,6 +95,9 @@
 
     /** H204 鐕冩枡1璁¢噺鍗曚綅鐮� -> 涓枃鍗曚綅 */
     private static final Map<String, String> ENERGY_FUEL_UNIT_NAMES = new HashMap<>();
+
+    /** 鑳借�楀鍏ユ寜鎶ヨ〃鏈熶簰鏂ワ紝闃叉鍚屾姤琛ㄦ湡骞跺彂閲嶅浜掔浉瑕嗙洊 */
+    private final ConcurrentHashMap<String, Object> energyImportLocks = new ConcurrentHashMap<>();
 
     static {
         ENERGY_VEHICLE_TYPE_NAMES.put("01", "鏅�氳揣杞�");
@@ -527,6 +531,11 @@
     /** 鑳借�楁槑缁嗘瘡缁勫浐瀹�18鍒楋紝杞︾墝鍙疯捣濮嬪垪锛�0-based锛夛細3,21,39,57,75 */
     private static final int[] ENERGY_GROUP_COLS = {3, 21, 39, 57, 75};
 
+    /** 鑳借�楀鍏ユ寜鎶ヨ〃鏈熶簰鏂ラ攣锛圚204 鏄庣粏涓庤繍鏀夸俊鎭叡鐢紝閬垮厤鍚屾姤琛ㄦ湡骞跺彂閲嶅浜掔浉瑕嗙洊锛� */
+    private Object energyLock(String period) {
+        return energyImportLocks.computeIfAbsent(period == null ? "" : period, k -> new Object());
+    }
+
     public ImportResult importEnergyMonthly(MultipartFile file, String period) throws Exception {
         List<EnergyRow> rows = new ArrayList<>();
         List<EnergyAuthVehicle> authList = new ArrayList<>();
@@ -541,7 +550,7 @@
                 if (enterpriseName == null || enterpriseName.trim().isEmpty()) continue;
                 for (int group : ENERGY_GROUP_COLS) {
                     String plate = getString(row, group);
-                    if (plate == null || plate.trim().isEmpty()) continue;
+                    if (plate == null || plate.trim().isEmpty() || "0".equals(plate.trim())) continue;
                     EnergyVehicleQuarterly e = new EnergyVehicleQuarterly();
                     e.setReportPeriod(period);
                     e.setRegionCode(getString(row, 0));
@@ -580,7 +589,7 @@
                     Row row = authSheet.getRow(r);
                     if (row == null) continue;
                     String plate = getString(row, 0);
-                    if (plate == null || plate.trim().isEmpty()) continue;
+                    if (plate == null || plate.trim().isEmpty() || "0".equals(plate.trim())) continue;
                     EnergyAuthVehicle auth = new EnergyAuthVehicle();
                     auth.setReportPeriod(period);
                     auth.setPlateNo(plate.trim());
@@ -597,54 +606,57 @@
         }
 
         // 骞傜瓑锛氬悓鎶ヨ〃鏈熼噸鏂板鍏ワ紝鍏堝垹闄ゆ棫鏁版嵁锛堜袱琛� + H204 瑙勫垯瀹℃牳缁撴灉锛�
-        energyMapper.delete(new LambdaQueryWrapper<EnergyVehicleQuarterly>()
-            .eq(EnergyVehicleQuarterly::getReportPeriod, period));
-        energyAuthMapper.delete(new LambdaQueryWrapper<EnergyAuthVehicle>()
-            .eq(EnergyAuthVehicle::getReportPeriod, period));
-        List<Long> h204RuleIds = new ArrayList<>();
-        for (com.trafficaudit.rulemanage.entity.AuditRule rule : ruleMapper.selectList(null)) {
-            if ("H204".equals(rule.getReportType())) h204RuleIds.add(rule.getId());
-        }
-        if (!h204RuleIds.isEmpty()) {
-            auditResultMapper.delete(new LambdaQueryWrapper<AuditResult>()
-                .eq(AuditResult::getReportPeriod, period)
-                .in(AuditResult::getRuleId, h204RuleIds));
-        }
-
-        int success = 0;
-        List<String> failDetails = new ArrayList<>();
-        for (EnergyRow item : rows) {
-            try {
-                energyMapper.insert(item.entity);
-                success++;
-            } catch (Exception e) {
-                Throwable cause = e;
-                while (cause.getCause() != null) cause = cause.getCause();
-                String reason = cause.getMessage();
-                if (reason == null || reason.trim().isEmpty()) reason = e.getMessage();
-                failDetails.add("绗� " + item.excelRow + " 琛岋紙" + item.entity.getEnterpriseName()
-                    + " " + item.entity.getPlateNo() + "锛夛細" + reason);
-                log.error("Energy insert error: row {}, {}", item.excelRow, item.entity.getPlateNo(), e);
+        // 鍔犻攣锛氬悓鎶ヨ〃鏈熷苟鍙戦噸瀵间簰鏂ワ紝闃叉 delete/insert 浜ら敊瀵艰嚧鏁版嵁娈嬬暀鎴栫炕鍊�
+        synchronized (energyLock(period)) {
+            energyMapper.delete(new LambdaQueryWrapper<EnergyVehicleQuarterly>()
+                .eq(EnergyVehicleQuarterly::getReportPeriod, period));
+            energyAuthMapper.delete(new LambdaQueryWrapper<EnergyAuthVehicle>()
+                .eq(EnergyAuthVehicle::getReportPeriod, period));
+            List<Long> h204RuleIds = new ArrayList<>();
+            for (com.trafficaudit.rulemanage.entity.AuditRule rule : ruleMapper.selectList(null)) {
+                if ("H204".equals(rule.getReportType())) h204RuleIds.add(rule.getId());
             }
-        }
-        String errorDetail = String.join("\n", failDetails);
-        if (errorDetail.length() > 4000) {
-            errorDetail = errorDetail.substring(0, 4000) + "\n鈥︹��";
-        }
-        recordBatch(file.getOriginalFilename(), "H204", period, rows.size(), success, failDetails.size(), errorDetail);
-
-        int authSuccess = 0;
-        for (EnergyAuthVehicle auth : authList) {
-            try {
-                energyAuthMapper.insert(auth);
-                authSuccess++;
-            } catch (Exception e) {
-                log.error("energy auth insert error: {}", auth.getPlateNo(), e);
+            if (!h204RuleIds.isEmpty()) {
+                auditResultMapper.delete(new LambdaQueryWrapper<AuditResult>()
+                    .eq(AuditResult::getReportPeriod, period)
+                    .in(AuditResult::getRuleId, h204RuleIds));
             }
+
+            int success = 0;
+            List<String> failDetails = new ArrayList<>();
+            for (EnergyRow item : rows) {
+                try {
+                    energyMapper.insert(item.entity);
+                    success++;
+                } catch (Exception e) {
+                    Throwable cause = e;
+                    while (cause.getCause() != null) cause = cause.getCause();
+                    String reason = cause.getMessage();
+                    if (reason == null || reason.trim().isEmpty()) reason = e.getMessage();
+                    failDetails.add("绗� " + item.excelRow + " 琛岋紙" + item.entity.getEnterpriseName()
+                        + " " + item.entity.getPlateNo() + "锛夛細" + reason);
+                    log.error("Energy insert error: row {}, {}", item.excelRow, item.entity.getPlateNo(), e);
+                }
+            }
+            String errorDetail = String.join("\n", failDetails);
+            if (errorDetail.length() > 4000) {
+                errorDetail = errorDetail.substring(0, 4000) + "\n鈥︹��";
+            }
+            recordBatch(file.getOriginalFilename(), "H204", period, rows.size(), success, failDetails.size(), errorDetail);
+
+            int authSuccess = 0;
+            for (EnergyAuthVehicle auth : authList) {
+                try {
+                    energyAuthMapper.insert(auth);
+                    authSuccess++;
+                } catch (Exception e) {
+                    log.error("energy auth insert error: {}", auth.getPlateNo(), e);
+                }
+            }
+            recordBatch(file.getOriginalFilename(), "ENERGY_AUTH", period, authList.size(), authSuccess, 0, null);
+            log.info("Energy monthly imported: {} vehicles, auth {} rows for {}", success, authSuccess, period);
+            return new ImportResult(success, failDetails.size(), failDetails);
         }
-        recordBatch(file.getOriginalFilename(), "ENERGY_AUTH", period, authList.size(), authSuccess, 0, null);
-        log.info("Energy monthly imported: {} vehicles, auth {} rows for {}", success, authSuccess, period);
-        return new ImportResult(success, failDetails.size(), failDetails);
     }
 
     /** 鑳借�楄溅杈嗚繍鏀夸俊鎭紙鐙珛妯℃澘锛氳溅鐗屽彿/杞﹁締绫诲瀷/鐕冩枡绫诲瀷/鏍囪鍚ㄤ綅/鍑嗙壍寮曡川閲忥級 */
@@ -657,7 +669,7 @@
                 Row row = sheet.getRow(r);
                 if (row == null) continue;
                 String plate = getString(row, 0);
-                if (plate == null || plate.trim().isEmpty()) continue;
+                if (plate == null || plate.trim().isEmpty() || "0".equals(plate.trim())) continue;
                 EnergyAuthVehicle auth = new EnergyAuthVehicle();
                 auth.setReportPeriod(period);
                 auth.setPlateNo(plate.trim());
@@ -671,30 +683,32 @@
             log.error("Energy auth parse error", e);
             throw e;
         }
-        // 骞傜瓑锛氬悓鎶ヨ〃鏈熼噸鏂板鍏ワ紝鍏堝垹闄ゆ棫鏁版嵁
-        energyAuthMapper.delete(new LambdaQueryWrapper<EnergyAuthVehicle>()
-            .eq(EnergyAuthVehicle::getReportPeriod, period));
-        deleteRuleResults("H204", period);
-        int success = 0;
-        List<String> failDetails = new ArrayList<>();
-        for (EnergyAuthVehicle auth : authList) {
-            try {
-                energyAuthMapper.insert(auth);
-                success++;
-            } catch (Exception e) {
-                Throwable cause = e;
-                while (cause.getCause() != null) cause = cause.getCause();
-                String reason = cause.getMessage();
-                if (reason == null || reason.trim().isEmpty()) reason = e.getMessage();
-                failDetails.add("绗� " + (authList.indexOf(auth) + 2) + " 琛岋紙" + auth.getPlateNo() + "锛夛細" + reason);
-                log.error("Energy auth insert error: {}", auth.getPlateNo(), e);
+        // 骞傜瓑锛氬悓鎶ヨ〃鏈熼噸鏂板鍏ワ紝鍏堝垹闄ゆ棫鏁版嵁锛涗笌 H204 鏄庣粏鍏辩敤鎶ヨ〃鏈熼攣锛岄槻骞跺彂浜掔浉瑕嗙洊
+        synchronized (energyLock(period)) {
+            energyAuthMapper.delete(new LambdaQueryWrapper<EnergyAuthVehicle>()
+                .eq(EnergyAuthVehicle::getReportPeriod, period));
+            deleteRuleResults("H204", period);
+            int success = 0;
+            List<String> failDetails = new ArrayList<>();
+            for (EnergyAuthVehicle auth : authList) {
+                try {
+                    energyAuthMapper.insert(auth);
+                    success++;
+                } catch (Exception e) {
+                    Throwable cause = e;
+                    while (cause.getCause() != null) cause = cause.getCause();
+                    String reason = cause.getMessage();
+                    if (reason == null || reason.trim().isEmpty()) reason = e.getMessage();
+                    failDetails.add("绗� " + (authList.indexOf(auth) + 2) + " 琛岋紙" + auth.getPlateNo() + "锛夛細" + reason);
+                    log.error("Energy auth insert error: {}", auth.getPlateNo(), e);
+                }
             }
+            String errorDetail = String.join("\n", failDetails);
+            if (errorDetail.length() > 4000) errorDetail = errorDetail.substring(0, 4000) + "\n鈥︹��";
+            recordBatch(file.getOriginalFilename(), "ENERGY_AUTH", period, authList.size(), success, failDetails.size(), errorDetail);
+            log.info("Energy auth imported: {} rows for {}", success, period);
+            return new ImportResult(success, failDetails.size(), failDetails);
         }
-        String errorDetail = String.join("\n", failDetails);
-        if (errorDetail.length() > 4000) errorDetail = errorDetail.substring(0, 4000) + "\n鈥︹��";
-        recordBatch(file.getOriginalFilename(), "ENERGY_AUTH", period, authList.size(), success, failDetails.size(), errorDetail);
-        log.info("Energy auth imported: {} rows for {}", success, period);
-        return new ImportResult(success, failDetails.size(), failDetails);
     }
 
     /** H204 琛岃褰曪細淇濈暀 Excel 琛屽彿鐢ㄤ簬澶辫触瀹氫綅 */

--
Gitblit v1.9.1