Przeglądaj źródła

台账导入-数据重复校验

chenshudong 5 dni temu
rodzic
commit
86a3b60b1a

+ 235 - 1
airport-admin/src/main/java/com/sundot/airport/web/controller/ledger/LedgerImportController.java

@@ -1,6 +1,8 @@
1 1
 package com.sundot.airport.web.controller.ledger;
2 2
 
3
+import cn.hutool.core.collection.CollUtil;
3 4
 import cn.hutool.core.date.DateUtil;
5
+import com.sundot.airport.common.dto.ImportResultVO;
4 6
 import com.sundot.airport.common.utils.poi.ExcelUtil;
5 7
 import com.sundot.airport.common.annotation.Log;
6 8
 import com.sundot.airport.common.core.controller.BaseController;
@@ -26,6 +28,7 @@ import java.util.ArrayList;
26 28
 import java.util.List;
27 29
 import java.util.Map;
28 30
 import java.util.UUID;
31
+import java.util.stream.Collectors;
29 32
 
30 33
 /**
31 34
  * 台账一键导入Controller
@@ -35,6 +38,7 @@ import java.util.UUID;
35 38
 @RequestMapping("/ledger/import")
36 39
 public class LedgerImportController extends BaseController {
37 40
 
41
+    private static final Integer START_LINE_NUMBER = 3;
38 42
     @Autowired private ILedgerSupervisionProblemService supervisionProblemService;
39 43
     @Autowired private ILedgerPatrolInspectionService patrolInspectionService;
40 44
     @Autowired private ILedgerRealtimeInterceptionService realtimeInterceptionService;
@@ -82,6 +86,29 @@ public class LedgerImportController extends BaseController {
82 86
             item.setSourceType("1");
83 87
             item.setCreateBy(getUsername());
84 88
         });
89
+        if (CollUtil.isNotEmpty(list)) {
90
+            List<LedgerSupervisionProblem> existList = supervisionProblemService.selectSupervisionProblemList(new LedgerSupervisionProblem());
91
+            List<String> repeatList = new ArrayList<>();
92
+            List<Integer> existIndexList = new ArrayList<>();
93
+            List<String> existConditionList = existList.stream().map(item -> item.getInspectedName() + "_" + item.getRecordDate()).collect(Collectors.toList());
94
+            for (int i = 0; i < list.size(); i++) {
95
+                LedgerSupervisionProblem item = list.get(i);
96
+                String tag = item.getInspectedName() + "_" + item.getRecordDate();
97
+                if (existConditionList.contains(tag)) {
98
+                    existIndexList.add(i + START_LINE_NUMBER);
99
+                } else {
100
+                    if (repeatList.contains(tag)) {
101
+                        existIndexList.add(i + START_LINE_NUMBER);
102
+                    } else {
103
+                        repeatList.add(tag);
104
+                    }
105
+                }
106
+            }
107
+            if (CollUtil.isNotEmpty(existIndexList)) {
108
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
109
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
110
+            }
111
+        }
85 112
         supervisionProblemService.batchInsert(list);
86 113
         return AjaxResult.success("导入成功,共" + list.size() + "条");
87 114
     }
@@ -128,6 +155,29 @@ public class LedgerImportController extends BaseController {
128 155
             item.setSourceType("1");
129 156
             item.setCreateBy(getUsername());
130 157
         });
158
+        if (CollUtil.isNotEmpty(list)) {
159
+            List<LedgerRealtimeInterception> existList = realtimeInterceptionService.selectList(new LedgerRealtimeInterception());
160
+            List<String> repeatList = new ArrayList<>();
161
+            List<Integer> existIndexList = new ArrayList<>();
162
+            List<String> existConditionList = existList.stream().map(item -> item.getInspectorName() + "_" + item.getRecordDate()).collect(Collectors.toList());
163
+            for (int i = 0; i < list.size(); i++) {
164
+                LedgerRealtimeInterception item = list.get(i);
165
+                String tag = item.getInspectorName() + "_" + item.getRecordDate();
166
+                if (existConditionList.contains(tag)) {
167
+                    existIndexList.add(i + START_LINE_NUMBER);
168
+                } else {
169
+                    if (repeatList.contains(tag)) {
170
+                        existIndexList.add(i + START_LINE_NUMBER);
171
+                    } else {
172
+                        repeatList.add(tag);
173
+                    }
174
+                }
175
+            }
176
+            if (CollUtil.isNotEmpty(existIndexList)) {
177
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
178
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
179
+            }
180
+        }
131 181
         realtimeInterceptionService.batchInsert(list);
132 182
         return AjaxResult.success("导入成功,共" + list.size() + "条");
133 183
     }
@@ -151,6 +201,29 @@ public class LedgerImportController extends BaseController {
151 201
             item.setSourceType("1");
152 202
             item.setCreateBy(getUsername());
153 203
         });
204
+        if (CollUtil.isNotEmpty(list)) {
205
+            List<LedgerServicePatrol> existList = servicePatrolService.selectList(new LedgerServicePatrol());
206
+            List<String> repeatList = new ArrayList<>();
207
+            List<Integer> existIndexList = new ArrayList<>();
208
+            List<String> existConditionList = existList.stream().map(item -> item.getInspectedName() + "_" + item.getRecordDate()).collect(Collectors.toList());
209
+            for (int i = 0; i < list.size(); i++) {
210
+                LedgerServicePatrol item = list.get(i);
211
+                String tag = item.getInspectedName() + "_" + item.getRecordDate();
212
+                if (existConditionList.contains(tag)) {
213
+                    existIndexList.add(i + START_LINE_NUMBER);
214
+                } else {
215
+                    if (repeatList.contains(tag)) {
216
+                        existIndexList.add(i + START_LINE_NUMBER);
217
+                    } else {
218
+                        repeatList.add(tag);
219
+                    }
220
+                }
221
+            }
222
+            if (CollUtil.isNotEmpty(existIndexList)) {
223
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
224
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
225
+            }
226
+        }
154 227
         servicePatrolService.batchInsert(list);
155 228
         return AjaxResult.success("导入成功,共" + list.size() + "条");
156 229
     }
@@ -197,6 +270,29 @@ public class LedgerImportController extends BaseController {
197 270
             item.setSourceType("1");
198 271
             item.setCreateBy(getUsername());
199 272
         });
273
+        if (CollUtil.isNotEmpty(list)) {
274
+            List<LedgerSecurityTest> existList = securityTestService.selectList(new LedgerSecurityTest());
275
+            List<String> repeatList = new ArrayList<>();
276
+            List<Integer> existIndexList = new ArrayList<>();
277
+            List<String> existConditionList = existList.stream().map(item -> item.getTestedName() + "_" + item.getRecordDate()).collect(Collectors.toList());
278
+            for (int i = 0; i < list.size(); i++) {
279
+                LedgerSecurityTest item = list.get(i);
280
+                String tag = item.getTestedName() + "_" + item.getRecordDate();
281
+                if (existConditionList.contains(tag)) {
282
+                    existIndexList.add(i + START_LINE_NUMBER);
283
+                } else {
284
+                    if (repeatList.contains(tag)) {
285
+                        existIndexList.add(i + START_LINE_NUMBER);
286
+                    } else {
287
+                        repeatList.add(tag);
288
+                    }
289
+                }
290
+            }
291
+            if (CollUtil.isNotEmpty(existIndexList)) {
292
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
293
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
294
+            }
295
+        }
200 296
         securityTestService.batchInsert(list);
201 297
         return AjaxResult.success("导入成功,共" + list.size() + "条");
202 298
     }
@@ -243,6 +339,29 @@ public class LedgerImportController extends BaseController {
243 339
             item.setSourceType("1");
244 340
             item.setCreateBy(getUsername());
245 341
         });
342
+        if (CollUtil.isNotEmpty(list)) {
343
+            List<LedgerUnsafeEvent> existList = unsafeEventService.selectList(new LedgerUnsafeEvent());
344
+            List<String> repeatList = new ArrayList<>();
345
+            List<Integer> existIndexList = new ArrayList<>();
346
+            List<String> existConditionList = existList.stream().map(item -> item.getResponsibleName() + "_" + item.getRecordDate()).collect(Collectors.toList());
347
+            for (int i = 0; i < list.size(); i++) {
348
+                LedgerUnsafeEvent item = list.get(i);
349
+                String tag = item.getResponsibleName() + "_" + item.getRecordDate();
350
+                if (existConditionList.contains(tag)) {
351
+                    existIndexList.add(i + START_LINE_NUMBER);
352
+                } else {
353
+                    if (repeatList.contains(tag)) {
354
+                        existIndexList.add(i + START_LINE_NUMBER);
355
+                    } else {
356
+                        repeatList.add(tag);
357
+                    }
358
+                }
359
+            }
360
+            if (CollUtil.isNotEmpty(existIndexList)) {
361
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
362
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
363
+            }
364
+        }
246 365
         unsafeEventService.batchInsert(list);
247 366
         return AjaxResult.success("导入成功,共" + list.size() + "条");
248 367
     }
@@ -275,6 +394,29 @@ public class LedgerImportController extends BaseController {
275 394
             cal.set(java.util.Calendar.SECOND, timeCal.get(java.util.Calendar.SECOND));
276 395
             item.setRecordDate(cal.getTime());
277 396
         });
397
+        if (CollUtil.isNotEmpty(list)) {
398
+            List<LedgerSeizureStats> existList = seizureStatsService.selectList(new LedgerSeizureStats());
399
+            List<String> repeatList = new ArrayList<>();
400
+            List<Integer> existIndexList = new ArrayList<>();
401
+            List<String> existConditionList = existList.stream().map(item -> item.getInspectorName() + "_" + item.getRecordDate()).collect(Collectors.toList());
402
+            for (int i = 0; i < list.size(); i++) {
403
+                LedgerSeizureStats item = list.get(i);
404
+                String tag = item.getInspectorName() + "_" + item.getRecordDate();
405
+                if (existConditionList.contains(tag)) {
406
+                    existIndexList.add(i + START_LINE_NUMBER);
407
+                } else {
408
+                    if (repeatList.contains(tag)) {
409
+                        existIndexList.add(i + START_LINE_NUMBER);
410
+                    } else {
411
+                        repeatList.add(tag);
412
+                    }
413
+                }
414
+            }
415
+            if (CollUtil.isNotEmpty(existIndexList)) {
416
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
417
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
418
+            }
419
+        }
278 420
         seizureStatsService.batchInsert(list);
279 421
         return AjaxResult.success("导入成功,共" + list.size() + "条");
280 422
     }
@@ -301,6 +443,29 @@ public class LedgerImportController extends BaseController {
301 443
             item.setSourceType("1");
302 444
             item.setCreateBy(getUsername());
303 445
         });
446
+        if (CollUtil.isNotEmpty(list)) {
447
+            List<LedgerTerminalBonus> existList = terminalBonusService.selectList(new LedgerTerminalBonus());
448
+            List<String> repeatList = new ArrayList<>();
449
+            List<Integer> existIndexList = new ArrayList<>();
450
+            List<String> existConditionList = existList.stream().map(item -> item.getPersonName() + "_" + item.getScoreDate()).collect(Collectors.toList());
451
+            for (int i = 0; i < list.size(); i++) {
452
+                LedgerTerminalBonus item = list.get(i);
453
+                String tag = item.getPersonName() + "_" + item.getScoreDate();
454
+                if (existConditionList.contains(tag)) {
455
+                    existIndexList.add(i + START_LINE_NUMBER);
456
+                } else {
457
+                    if (repeatList.contains(tag)) {
458
+                        existIndexList.add(i + START_LINE_NUMBER);
459
+                    } else {
460
+                        repeatList.add(tag);
461
+                    }
462
+                }
463
+            }
464
+            if (CollUtil.isNotEmpty(existIndexList)) {
465
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
466
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
467
+            }
468
+        }
304 469
         terminalBonusService.batchInsert(list);
305 470
         return AjaxResult.success("导入成功,共" + list.size() + "条");
306 471
     }
@@ -347,6 +512,29 @@ public class LedgerImportController extends BaseController {
347 512
             item.setSourceType("1");
348 513
             item.setCreateBy(getUsername());
349 514
         });
515
+        if (CollUtil.isNotEmpty(list)) {
516
+            List<LedgerRewardApproval> existList = rewardApprovalService.selectList(new LedgerRewardApproval());
517
+            List<String> repeatList = new ArrayList<>();
518
+            List<Integer> existIndexList = new ArrayList<>();
519
+            List<String> existConditionList = existList.stream().map(item -> item.getPersonName() + "_" + item.getApproveDate()).collect(Collectors.toList());
520
+            for (int i = 0; i < list.size(); i++) {
521
+                LedgerRewardApproval item = list.get(i);
522
+                String tag = item.getPersonName() + "_" + item.getApproveDate();
523
+                if (existConditionList.contains(tag)) {
524
+                    existIndexList.add(i + START_LINE_NUMBER);
525
+                } else {
526
+                    if (repeatList.contains(tag)) {
527
+                        existIndexList.add(i + START_LINE_NUMBER);
528
+                    } else {
529
+                        repeatList.add(tag);
530
+                    }
531
+                }
532
+            }
533
+            if (CollUtil.isNotEmpty(existIndexList)) {
534
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
535
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
536
+            }
537
+        }
350 538
         rewardApprovalService.batchInsert(list);
351 539
         return AjaxResult.success("导入成功,共" + list.size() + "条");
352 540
     }
@@ -488,6 +676,29 @@ public class LedgerImportController extends BaseController {
488 676
             return AjaxResult.error("导入数据为空或解析失败,请检查Excel表头是否与模板一致");
489 677
         }
490 678
         list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
679
+        if (CollUtil.isNotEmpty(list)) {
680
+            List<LedgerLeaveSpecial> existList = leaveSpecialService.selectList(new LedgerLeaveSpecial());
681
+            List<String> repeatList = new ArrayList<>();
682
+            List<Integer> existIndexList = new ArrayList<>();
683
+            List<String> existConditionList = existList.stream().map(item -> item.getPersonName() + "_" + item.getStartDate() + "_" + item.getEndDate()).collect(Collectors.toList());
684
+            for (int i = 0; i < list.size(); i++) {
685
+                LedgerLeaveSpecial item = list.get(i);
686
+                String tag = item.getPersonName() + "_" + item.getStartDate() + "_" + item.getEndDate();
687
+                if (existConditionList.contains(tag)) {
688
+                    existIndexList.add(i + START_LINE_NUMBER);
689
+                } else {
690
+                    if (repeatList.contains(tag)) {
691
+                        existIndexList.add(i + START_LINE_NUMBER);
692
+                    } else {
693
+                        repeatList.add(tag);
694
+                    }
695
+                }
696
+            }
697
+            if (CollUtil.isNotEmpty(existIndexList)) {
698
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
699
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
700
+            }
701
+        }
491 702
         leaveSpecialService.batchInsert(list);
492 703
         return AjaxResult.success("导入成功,共" + list.size() + "条");
493 704
     }
@@ -534,6 +745,29 @@ public class LedgerImportController extends BaseController {
534 745
             return AjaxResult.error("导入数据为空或解析失败,请检查Excel表头是否与模板一致");
535 746
         }
536 747
         list.forEach(item -> { item.setImportBatch(batchNo); item.setSourceType("1"); item.setCreateBy(getUsername()); });
748
+        if (CollUtil.isNotEmpty(list)) {
749
+            List<LedgerQualificationLevel> existList = qualificationLevelService.selectQueryList(new LedgerQualificationLevel());
750
+            List<String> repeatList = new ArrayList<>();
751
+            List<Integer> existIndexList = new ArrayList<>();
752
+            List<String> existConditionList = existList.stream().map(item -> item.getPersonName()).collect(Collectors.toList());
753
+            for (int i = 0; i < list.size(); i++) {
754
+                LedgerQualificationLevel item = list.get(i);
755
+                String tag = item.getPersonName();
756
+                if (existConditionList.contains(item.getPersonName())) {
757
+                    existIndexList.add(i + START_LINE_NUMBER);
758
+                } else {
759
+                    if (repeatList.contains(tag)) {
760
+                        existIndexList.add(i + START_LINE_NUMBER);
761
+                    } else {
762
+                        repeatList.add(tag);
763
+                    }
764
+                }
765
+            }
766
+            if (CollUtil.isNotEmpty(existIndexList)) {
767
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
768
+                return AjaxResult.error("导入失败,第【" + repeatNum + "】行数据重复,请检查台账");
769
+            }
770
+        }
537 771
         qualificationLevelService.batchInsert(list);
538 772
         return AjaxResult.success("导入成功,共" + list.size() + "条");
539 773
     }
@@ -547,7 +781,7 @@ public class LedgerImportController extends BaseController {
547 781
     @PostMapping("/combined")
548 782
     public AjaxResult importCombined(@RequestParam("file") MultipartFile file) throws Exception {
549 783
         String batchNo = generateBatchNo();
550
-        Map<String, String> result = combinedImportService.importAll(file, batchNo, getUsername());
784
+        List<ImportResultVO> result = combinedImportService.importAll(file, batchNo, getUsername());
551 785
         return AjaxResult.success(result);
552 786
     }
553 787
 

+ 39 - 0
airport-common/src/main/java/com/sundot/airport/common/dto/ImportResultDto.java

@@ -0,0 +1,39 @@
1
+package com.sundot.airport.common.dto;
2
+
3
+import lombok.AllArgsConstructor;
4
+import lombok.Builder;
5
+import lombok.Data;
6
+import lombok.NoArgsConstructor;
7
+
8
+import java.io.Serializable;
9
+
10
+/**
11
+ * 导入结果通用报文
12
+ *
13
+ * @author ruoyi
14
+ * @date 2025-09-07
15
+ */
16
+@Data
17
+@Builder
18
+@NoArgsConstructor
19
+@AllArgsConstructor
20
+public class ImportResultDto implements Serializable {
21
+
22
+    private static final long serialVersionUID = 1L;
23
+
24
+    /**
25
+     * 导入数量
26
+     */
27
+    private Integer importNum;
28
+
29
+    /**
30
+     * 跳过数量
31
+     */
32
+    private Integer skipNum;
33
+
34
+    /**
35
+     * 重复行数描述
36
+     */
37
+    private String repeatNumDesc;
38
+
39
+}

+ 34 - 0
airport-common/src/main/java/com/sundot/airport/common/dto/ImportResultVO.java

@@ -0,0 +1,34 @@
1
+package com.sundot.airport.common.dto;
2
+
3
+import lombok.AllArgsConstructor;
4
+import lombok.Builder;
5
+import lombok.Data;
6
+import lombok.NoArgsConstructor;
7
+
8
+import java.io.Serializable;
9
+
10
+/**
11
+ * 导入结果报文
12
+ *
13
+ * @author ruoyi
14
+ * @date 2025-09-07
15
+ */
16
+@Data
17
+@Builder
18
+@NoArgsConstructor
19
+@AllArgsConstructor
20
+public class ImportResultVO implements Serializable {
21
+
22
+    private static final long serialVersionUID = 1L;
23
+
24
+    /**
25
+     * 表名
26
+     */
27
+    private String sheetName;
28
+
29
+    /**
30
+     * 导入结果
31
+     */
32
+    private String sheetResult;
33
+
34
+}

+ 3 - 1
airport-ledger/src/main/java/com/sundot/airport/ledger/service/ILedgerCombinedImportService.java

@@ -1,7 +1,9 @@
1 1
 package com.sundot.airport.ledger.service;
2 2
 
3
+import com.sundot.airport.common.dto.ImportResultVO;
3 4
 import org.springframework.web.multipart.MultipartFile;
4 5
 
6
+import java.util.List;
5 7
 import java.util.Map;
6 8
 
7 9
 /**
@@ -18,7 +20,7 @@ public interface ILedgerCombinedImportService {
18 20
      * @param username 操作人
19 21
      * @return Map<Sheet名, 导入结果描述>
20 22
      */
21
-    Map<String, String> importAll(MultipartFile file, String batchNo, String username) throws Exception;
23
+    List<ImportResultVO> importAll(MultipartFile file, String batchNo, String username) throws Exception;
22 24
 
23 25
     /**
24 26
      * 按导入时间范围清理全部台账表数据(20张表 + 台账同步配分事项)

+ 301 - 37
airport-ledger/src/main/java/com/sundot/airport/ledger/service/impl/LedgerCombinedImportServiceImpl.java

@@ -1,9 +1,15 @@
1 1
 package com.sundot.airport.ledger.service.impl;
2 2
 
3
+import cn.hutool.core.collection.CollUtil;
4
+import cn.hutool.core.text.StrBuilder;
5
+import cn.hutool.core.util.ObjUtil;
6
+import cn.hutool.core.util.StrUtil;
3 7
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
4 8
 import com.baomidou.mybatisplus.extension.service.IService;
5 9
 import com.sundot.airport.common.core.domain.entity.SysDept;
6 10
 import com.sundot.airport.common.core.domain.entity.SysUser;
11
+import com.sundot.airport.common.dto.ImportResultDto;
12
+import com.sundot.airport.common.dto.ImportResultVO;
7 13
 import com.sundot.airport.common.enums.DeptType;
8 14
 import com.sundot.airport.system.domain.SysPost;
9 15
 import com.sundot.airport.system.domain.BasePosition;
@@ -45,6 +51,7 @@ import java.util.stream.Collectors;
45 51
 @Service
46 52
 public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportService {
47 53
 
54
+    private static final Integer START_LINE_NUMBER = 3;
48 55
     @Autowired private ILedgerSupervisionProblemService supervisionProblemService;
49 56
     @Autowired private ILedgerPatrolInspectionService patrolInspectionService;
50 57
     @Autowired private ILedgerRealtimeInterceptionService realtimeInterceptionService;
@@ -109,8 +116,8 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
109 116
     // ════════════════════════════════════════════════════════════════
110 117
     @Override
111 118
     @Transactional(rollbackFor = Exception.class)
112
-    public Map<String, String> importAll(MultipartFile file, String batchNo, String username) throws Exception {
113
-        Map<String, String> result = new LinkedHashMap<>();
119
+    public List<ImportResultVO> importAll(MultipartFile file, String batchNo, String username) throws Exception {
120
+        List<ImportResultVO> result = new ArrayList<>();
114 121
         boolean hasError = false;
115 122
         try (Workbook wb = WorkbookFactory.create(file.getInputStream())) {
116 123
             buildImportCache();
@@ -120,14 +127,22 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
120 127
                 String handler   = entry.getValue();
121 128
                 Sheet sheet = wb.getSheet(sheetName);
122 129
                 if (sheet == null) {
123
-                    result.put(sheetName, "未找到该Sheet,跳过");
130
+                    result.add(ImportResultVO.builder().sheetName(sheetName).sheetResult("未找到该Sheet,跳过").build());
124 131
                     continue;
125 132
                 }
126 133
                 try {
127
-                    int count = self.dispatchInNestedTransaction(sheet, handler, batchNo, username);
128
-                    result.put(sheetName, "导入成功 " + count + " 条");
134
+                    ImportResultDto resultDto = self.dispatchInNestedTransaction(sheet, handler, batchNo, username);
135
+                    StrBuilder sb = new StrBuilder();
136
+                    sb.append("导入【").append(String.valueOf(resultDto.getImportNum())).append("】条");
137
+                    if (ObjUtil.isNotNull(resultDto.getSkipNum())) {
138
+                        sb.append(",跳过【").append(String.valueOf(resultDto.getSkipNum())).append("】条");
139
+                    }
140
+                    if (StrUtil.isNotEmpty(resultDto.getRepeatNumDesc())) {
141
+                        sb.append(",第【").append(resultDto.getRepeatNumDesc()).append("】行数据重复,请检查台账");
142
+                    }
143
+                    result.add(ImportResultVO.builder().sheetName(sheetName).sheetResult(sb.toString()).build());
129 144
                 } catch (Exception e) {
130
-                    result.put(sheetName, "导入失败: " + e.getMessage());
145
+                    result.add(ImportResultVO.builder().sheetName(sheetName).sheetResult("导入失败: " + e.getMessage()).build());
131 146
                     hasError = true;
132 147
                 }
133 148
             }
@@ -142,11 +157,11 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
142 157
 
143 158
 
144 159
     @Transactional(propagation = Propagation.NESTED, rollbackFor = Exception.class)
145
-    public int dispatchInNestedTransaction(Sheet sheet, String handler, String batchNo, String username) {
160
+    public ImportResultDto dispatchInNestedTransaction(Sheet sheet, String handler, String batchNo, String username) {
146 161
         return dispatch(sheet, handler, batchNo, username);
147 162
     }
148 163
 
149
-    private int dispatch(Sheet sheet, String handler, String batchNo, String username) {
164
+    private ImportResultDto dispatch(Sheet sheet, String handler, String batchNo, String username) {
150 165
         switch (handler) {
151 166
             case "supervisionProblem":    return doSupervisionProblem(sheet, batchNo, username);
152 167
 //            case "patrolInspection":      return doPatrolInspection(sheet, batchNo, username);
@@ -169,7 +184,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
169 184
 //            case "healthSoldier":         return doHealthSoldier(sheet, batchNo, username);
170 185
 //            case "dormFireSafety":        return doDormFireSafety(sheet, batchNo, username);
171 186
 //            case "trainingIssue":         return doTrainingIssue(sheet, batchNo, username);
172
-            default: return 0;
187
+            default: return ImportResultDto.builder().importNum(0).build();
173 188
         }
174 189
     }
175 190
 
@@ -182,7 +197,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
182 197
      *          问题类型(6) 整改措施(7) 依据(8) 问题层级(9) 附件(10)
183 198
      *          整改情况(11) 整改佐证材料(12) 巡查人员(13)
184 199
      */
185
-    private int doSupervisionProblem(Sheet sheet, String batchNo, String username) {
200
+    private ImportResultDto doSupervisionProblem(Sheet sheet, String batchNo, String username) {
186 201
         List<LedgerSupervisionProblem> list = new ArrayList<>();
187 202
         for (Object[] c : dataRows(sheet, 2)) {
188 203
             LedgerSupervisionProblem o = new LedgerSupervisionProblem();
@@ -248,8 +263,33 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
248 263
             o.setCreateBy(username);
249 264
             list.add(o);
250 265
         }
266
+        if (CollUtil.isNotEmpty(list)) {
267
+            List<LedgerSupervisionProblem> existList = supervisionProblemService.selectSupervisionProblemList(new LedgerSupervisionProblem());
268
+            List<String> repeatList = new ArrayList<>();
269
+            Integer skipNum = 0;
270
+            List<Integer> existIndexList = new ArrayList<>();
271
+            List<String> existConditionList = existList.stream().map(item -> item.getInspectedName() + "_" + item.getRecordDate()).collect(Collectors.toList());
272
+            for (int i = 0; i < list.size(); i++) {
273
+                LedgerSupervisionProblem item = list.get(i);
274
+                String tag = item.getInspectedName() + "_" + item.getRecordDate();
275
+                if (existConditionList.contains(tag)) {
276
+                    existIndexList.add(i + START_LINE_NUMBER);
277
+                } else {
278
+                    if (repeatList.contains(tag)) {
279
+                        existIndexList.add(i + START_LINE_NUMBER);
280
+                    } else {
281
+                        repeatList.add(tag);
282
+                        skipNum++;
283
+                    }
284
+                }
285
+            }
286
+            if (CollUtil.isNotEmpty(existIndexList)) {
287
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
288
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
289
+            }
290
+        }
251 291
         supervisionProblemService.batchInsert(list);
252
-        return list.size();
292
+        return ImportResultDto.builder().importNum(list.size()).build();
253 293
     }
254 294
 
255 295
     /** 2. 队室三级质控巡查记录表 → ledger_patrol_inspection
@@ -336,7 +376,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
336 376
      * 导入顺序:时间(0) 区域(1) 工作点(2) 岗位(3) 责任人(4) 实时质控拦截物品(5)
337 377
      *          个数(6) 问题层级(7) 附件(8) 检查人员(9)
338 378
      */
339
-    private int doRealtimeInterception(Sheet sheet, String batchNo, String username) {
379
+    private ImportResultDto doRealtimeInterception(Sheet sheet, String batchNo, String username) {
340 380
         List<LedgerRealtimeInterception> list = new ArrayList<>();
341 381
         for (Object[] c : dataRows(sheet, 2)) {
342 382
             LedgerRealtimeInterception o = new LedgerRealtimeInterception();
@@ -400,8 +440,33 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
400 440
             o.setCreateBy(username);
401 441
             list.add(o);
402 442
         }
443
+        if (CollUtil.isNotEmpty(list)) {
444
+            List<LedgerRealtimeInterception> existList = realtimeInterceptionService.selectList(new LedgerRealtimeInterception());
445
+            List<String> repeatList = new ArrayList<>();
446
+            Integer skipNum = 0;
447
+            List<Integer> existIndexList = new ArrayList<>();
448
+            List<String> existConditionList = existList.stream().map(item -> item.getInspectorName() + "_" + item.getRecordDate()).collect(Collectors.toList());
449
+            for (int i = 0; i < list.size(); i++) {
450
+                LedgerRealtimeInterception item = list.get(i);
451
+                String tag = item.getInspectorName() + "_" + item.getRecordDate();
452
+                if (existConditionList.contains(tag)) {
453
+                    existIndexList.add(i + START_LINE_NUMBER);
454
+                } else {
455
+                    if (repeatList.contains(tag)) {
456
+                        existIndexList.add(i + START_LINE_NUMBER);
457
+                    } else {
458
+                        repeatList.add(tag);
459
+                        skipNum++;
460
+                    }
461
+                }
462
+            }
463
+            if (CollUtil.isNotEmpty(existIndexList)) {
464
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
465
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
466
+            }
467
+        }
403 468
         realtimeInterceptionService.batchInsert(list);
404
-        return list.size();
469
+        return ImportResultDto.builder().importNum(list.size()).build();
405 470
     }
406 471
 
407 472
     /** 4. 服务巡查 → ledger_service_patrol
@@ -409,7 +474,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
409 474
      *          问题类型(6) 整改措施(7) 问题层级(8) 附件(9) 整改情况(10)
410 475
      *          佐证材料(11) 检查人员(12)
411 476
      */
412
-    private int doServicePatrol(Sheet sheet, String batchNo, String username) {
477
+    private ImportResultDto doServicePatrol(Sheet sheet, String batchNo, String username) {
413 478
         List<LedgerServicePatrol> list = new ArrayList<>();
414 479
         for (Object[] c : dataRows(sheet, 2)) {
415 480
             LedgerServicePatrol o = new LedgerServicePatrol();
@@ -477,15 +542,40 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
477 542
             o.setCreateBy(username);
478 543
             list.add(o);
479 544
         }
545
+        if (CollUtil.isNotEmpty(list)) {
546
+            List<LedgerServicePatrol> existList = servicePatrolService.selectList(new LedgerServicePatrol());
547
+            List<String> repeatList = new ArrayList<>();
548
+            Integer skipNum = 0;
549
+            List<Integer> existIndexList = new ArrayList<>();
550
+            List<String> existConditionList = existList.stream().map(item -> item.getInspectedName() + "_" + item.getRecordDate()).collect(Collectors.toList());
551
+            for (int i = 0; i < list.size(); i++) {
552
+                LedgerServicePatrol item = list.get(i);
553
+                String tag = item.getInspectedName() + "_" + item.getRecordDate();
554
+                if (existConditionList.contains(tag)) {
555
+                    existIndexList.add(i + START_LINE_NUMBER);
556
+                } else {
557
+                    if (repeatList.contains(tag)) {
558
+                        existIndexList.add(i + START_LINE_NUMBER);
559
+                    } else {
560
+                        repeatList.add(tag);
561
+                        skipNum++;
562
+                    }
563
+                }
564
+            }
565
+            if (CollUtil.isNotEmpty(existIndexList)) {
566
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
567
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
568
+            }
569
+        }
480 570
         servicePatrolService.batchInsert(list);
481
-        return list.size();
571
+        return ImportResultDto.builder().importNum(list.size()).build();
482 572
     }
483 573
 
484 574
     /** 5. 投诉情况 → ledger_complaint
485 575
      * R2: 时间(0) 航班号(1) 旅客姓名(2) 责任人(3) 投诉情况(4)
486 576
      *     旅客诉求(5) 类别(6) 渠道来源(7) 是否有责(8) 处理进度(9)
487 577
      */
488
-    private int doComplaint(Sheet sheet, String batchNo, String username) {
578
+    private ImportResultDto doComplaint(Sheet sheet, String batchNo, String username) {
489 579
         List<LedgerComplaint> list = new ArrayList<>();
490 580
         for (Object[] c : dataRows(sheet, 2)) {
491 581
             LedgerComplaint o = new LedgerComplaint();
@@ -522,7 +612,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
522 612
             list.add(o);
523 613
         }
524 614
         complaintService.batchInsert(list);
525
-        return list.size();
615
+        return ImportResultDto.builder().importNum(list.size()).build();
526 616
     }
527 617
 
528 618
     /** 6. 安保测试记录表(部门)→ ledger_security_test
@@ -530,7 +620,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
530 620
      *          被测试人员(5) 被测试岗位(6) 测试物品(7) 图片或视频(8) 是否通过(9)
531 621
      *          层级(10) 整改措施(11) 整改材料(12)
532 622
      */
533
-    private int doSecurityTest(Sheet sheet, String batchNo, String username) {
623
+    private ImportResultDto doSecurityTest(Sheet sheet, String batchNo, String username) {
534 624
         List<LedgerSecurityTest> list = new ArrayList<>();
535 625
         for (Object[] c : dataRows(sheet, 2)) {
536 626
             LedgerSecurityTest o = new LedgerSecurityTest();
@@ -623,9 +713,33 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
623 713
                 }
624 714
             }
625 715
         }
626
-        
716
+        if (CollUtil.isNotEmpty(list)) {
717
+            List<LedgerSecurityTest> existList = securityTestService.selectList(new LedgerSecurityTest());
718
+            List<String> repeatList = new ArrayList<>();
719
+            Integer skipNum = 0;
720
+            List<Integer> existIndexList = new ArrayList<>();
721
+            List<String> existConditionList = existList.stream().map(item -> item.getTestedName() + "_" + item.getRecordDate()).collect(Collectors.toList());
722
+            for (int i = 0; i < list.size(); i++) {
723
+                LedgerSecurityTest item = list.get(i);
724
+                String tag = item.getTestedName() + "_" + item.getRecordDate();
725
+                if (existConditionList.contains(tag)) {
726
+                    existIndexList.add(i + START_LINE_NUMBER);
727
+                } else {
728
+                    if (repeatList.contains(tag)) {
729
+                        existIndexList.add(i + START_LINE_NUMBER);
730
+                    } else {
731
+                        repeatList.add(tag);
732
+                        skipNum++;
733
+                    }
734
+                }
735
+            }
736
+            if (CollUtil.isNotEmpty(existIndexList)) {
737
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
738
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
739
+            }
740
+        }
627 741
         securityTestService.batchInsert(list);
628
-        return list.size();
742
+        return ImportResultDto.builder().importNum(list.size()).build();
629 743
     }
630 744
 
631 745
     /** 7. 通道过检率(pivot表)→ ledger_channel_pass_rate
@@ -633,9 +747,9 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
633 747
      * R2: 小组(0) 2026年1月平均过检率(1) 2026年2月...(2) ...
634 748
      * 每行展开为多条(每月一条)
635 749
      */
636
-    private int doChannelPassRate(Sheet sheet, String batchNo, String username) {
750
+    private ImportResultDto doChannelPassRate(Sheet sheet, String batchNo, String username) {
637 751
         Row headerRow = sheet.getRow(1);
638
-        if (headerRow == null) return 0;
752
+        if (headerRow == null) return ImportResultDto.builder().importNum(0).build();
639 753
 
640 754
         // 找月份列(从列1开始)
641 755
         List<int[]> monthCols = new ArrayList<>();
@@ -688,7 +802,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
688 802
             }
689 803
         }
690 804
         channelPassRateService.batchInsert(list);
691
-        return list.size();
805
+        return ImportResultDto.builder().importNum(list.size()).build();
692 806
     }
693 807
 
694 808
     /**
@@ -727,7 +841,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
727 841
      * R2: 时间(0) 事件描述(1) 类别(2) 航班号(3) 责任人(4)
728 842
      *     涉及物品(5) 岗位(6) 区域(7) 通道号(8) 附件(9)
729 843
      */
730
-    private int doUnsafeEvent(Sheet sheet, String batchNo, String username) {
844
+    private ImportResultDto doUnsafeEvent(Sheet sheet, String batchNo, String username) {
731 845
         List<LedgerUnsafeEvent> list = new ArrayList<>();
732 846
         for (Object[] c : dataRows(sheet, 2)) {
733 847
             LedgerUnsafeEvent o = new LedgerUnsafeEvent();
@@ -789,8 +903,33 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
789 903
             o.setCreateBy(username);
790 904
             list.add(o);
791 905
         }
906
+        if (CollUtil.isNotEmpty(list)) {
907
+            List<LedgerUnsafeEvent> existList = unsafeEventService.selectList(new LedgerUnsafeEvent());
908
+            List<String> repeatList = new ArrayList<>();
909
+            Integer skipNum = 0;
910
+            List<Integer> existIndexList = new ArrayList<>();
911
+            List<String> existConditionList = existList.stream().map(item -> item.getResponsibleName() + "_" + item.getRecordDate()).collect(Collectors.toList());
912
+            for (int i = 0; i < list.size(); i++) {
913
+                LedgerUnsafeEvent item = list.get(i);
914
+                String tag = item.getResponsibleName() + "_" + item.getRecordDate();
915
+                if (existConditionList.contains(tag)) {
916
+                    existIndexList.add(i + START_LINE_NUMBER);
917
+                } else {
918
+                    if (repeatList.contains(tag)) {
919
+                        existIndexList.add(i + START_LINE_NUMBER);
920
+                    } else {
921
+                        repeatList.add(tag);
922
+                        skipNum++;
923
+                    }
924
+                }
925
+            }
926
+            if (CollUtil.isNotEmpty(existIndexList)) {
927
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
928
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
929
+            }
930
+        }
792 931
         unsafeEventService.batchInsert(list);
793
-        return list.size();
932
+        return ImportResultDto.builder().importNum(list.size()).build();
794 933
     }
795 934
 
796 935
     /** 9. 2026查获违规品统计 → ledger_seizure_stats
@@ -800,7 +939,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
800 939
      *     违规物品(16) 二级分类(17) 数量(18) 事件简况(19) 查获位置(20)
801 940
      *     处理结果(21) 备注(22)
802 941
      */
803
-    private int doSeizureStats(Sheet sheet, String batchNo, String username) {
942
+    private ImportResultDto doSeizureStats(Sheet sheet, String batchNo, String username) {
804 943
         List<LedgerSeizureStats> list = new ArrayList<>();
805 944
         for (Object[] c : dataRows(sheet, 2)) {
806 945
             LedgerSeizureStats o = new LedgerSeizureStats();
@@ -881,14 +1020,39 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
881 1020
             o.setCreateBy(username);
882 1021
             list.add(o);
883 1022
         }
1023
+        if (CollUtil.isNotEmpty(list)) {
1024
+            List<LedgerSeizureStats> existList = seizureStatsService.selectList(new LedgerSeizureStats());
1025
+            List<String> repeatList = new ArrayList<>();
1026
+            Integer skipNum = 0;
1027
+            List<Integer> existIndexList = new ArrayList<>();
1028
+            List<String> existConditionList = existList.stream().map(item -> item.getInspectorName() + "_" + item.getRecordDate()).collect(Collectors.toList());
1029
+            for (int i = 0; i < list.size(); i++) {
1030
+                LedgerSeizureStats item = list.get(i);
1031
+                String tag = item.getInspectorName() + "_" + item.getRecordDate();
1032
+                if (existConditionList.contains(tag)) {
1033
+                    existIndexList.add(i + START_LINE_NUMBER);
1034
+                } else {
1035
+                    if (repeatList.contains(tag)) {
1036
+                        existIndexList.add(i + START_LINE_NUMBER);
1037
+                    } else {
1038
+                        repeatList.add(tag);
1039
+                        skipNum++;
1040
+                    }
1041
+                }
1042
+            }
1043
+            if (CollUtil.isNotEmpty(existIndexList)) {
1044
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
1045
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
1046
+            }
1047
+        }
884 1048
         seizureStatsService.batchInsert(list);
885
-        return list.size();
1049
+        return ImportResultDto.builder().importNum(list.size()).build();
886 1050
     }
887 1051
 
888 1052
     /** 10. 航站楼加分 → ledger_terminal_bonus
889 1053
      * R2: 姓名(0) 所属航站楼(1) 记分值(2) 记分日期(3) 捡到物品金额(4) 记分条款(5)
890 1054
      */
891
-    private int doTerminalBonus(Sheet sheet, String batchNo, String username) {
1055
+    private ImportResultDto doTerminalBonus(Sheet sheet, String batchNo, String username) {
892 1056
         List<LedgerTerminalBonus> list = new ArrayList<>();
893 1057
         for (Object[] c : dataRows(sheet, 2)) {
894 1058
             LedgerTerminalBonus o = new LedgerTerminalBonus();
@@ -919,14 +1083,39 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
919 1083
             
920 1084
             list.add(o);
921 1085
         }
1086
+        if (CollUtil.isNotEmpty(list)) {
1087
+            List<LedgerTerminalBonus> existList = terminalBonusService.selectList(new LedgerTerminalBonus());
1088
+            List<String> repeatList = new ArrayList<>();
1089
+            Integer skipNum = 0;
1090
+            List<Integer> existIndexList = new ArrayList<>();
1091
+            List<String> existConditionList = existList.stream().map(item -> item.getPersonName() + "_" + item.getScoreDate()).collect(Collectors.toList());
1092
+            for (int i = 0; i < list.size(); i++) {
1093
+                LedgerTerminalBonus item = list.get(i);
1094
+                String tag = item.getPersonName() + "_" + item.getScoreDate();
1095
+                if (existConditionList.contains(tag)) {
1096
+                    existIndexList.add(i + START_LINE_NUMBER);
1097
+                } else {
1098
+                    if (repeatList.contains(tag)) {
1099
+                        existIndexList.add(i + START_LINE_NUMBER);
1100
+                    } else {
1101
+                        repeatList.add(tag);
1102
+                        skipNum++;
1103
+                    }
1104
+                }
1105
+            }
1106
+            if (CollUtil.isNotEmpty(existIndexList)) {
1107
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
1108
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
1109
+            }
1110
+        }
922 1111
         terminalBonusService.batchInsert(list);
923
-        return list.size();
1112
+        return ImportResultDto.builder().importNum(list.size()).build();
924 1113
     }
925 1114
 
926 1115
     /** 11. 成绩收集 → ledger_exam_score
927 1116
      * R2: 类别(0) 期数(1) 考试人员(2) 理论成绩(3) 图像成绩(4)
928 1117
      */
929
-    private int doExamScore(Sheet sheet, String batchNo, String username) {
1118
+    private ImportResultDto doExamScore(Sheet sheet, String batchNo, String username) {
930 1119
         List<LedgerExamScore> list = new ArrayList<>();
931 1120
         for (Object[] c : dataRows(sheet, 2)) {
932 1121
             LedgerExamScore o = new LedgerExamScore();
@@ -957,7 +1146,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
957 1146
             list.add(o);
958 1147
         }
959 1148
         examScoreService.batchInsert(list);
960
-        return list.size();
1149
+        return ImportResultDto.builder().importNum(list.size()).build();
961 1150
     }
962 1151
 
963 1152
     /** 12. 小额奖励审批单-安检-质控 → ledger_reward_approval
@@ -965,7 +1154,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
965 1154
      * R1: 姓名(0) 查获(事件)时间(1) 奖励类别(2) 查获物品(3) 人员类别(4)
966 1155
      *     主要事由简述(5) 处置结果(6) 证明材料(7)
967 1156
      */
968
-    private int doRewardApproval(Sheet sheet, String batchNo, String username) {
1157
+    private ImportResultDto doRewardApproval(Sheet sheet, String batchNo, String username) {
969 1158
         List<LedgerRewardApproval> list = new ArrayList<>();
970 1159
         for (Object[] c : dataRows(sheet, 2)) {  // 跳2行表头
971 1160
             LedgerRewardApproval o = new LedgerRewardApproval();
@@ -996,8 +1185,33 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
996 1185
             o.setCreateBy(username);
997 1186
             list.add(o);
998 1187
         }
1188
+        if (CollUtil.isNotEmpty(list)) {
1189
+            List<LedgerRewardApproval> existList = rewardApprovalService.selectList(new LedgerRewardApproval());
1190
+            List<String> repeatList = new ArrayList<>();
1191
+            Integer skipNum = 0;
1192
+            List<Integer> existIndexList = new ArrayList<>();
1193
+            List<String> existConditionList = existList.stream().map(item -> item.getPersonName() + "_" + item.getApproveDate()).collect(Collectors.toList());
1194
+            for (int i = 0; i < list.size(); i++) {
1195
+                LedgerRewardApproval item = list.get(i);
1196
+                String tag = item.getPersonName() + "_" + item.getApproveDate();
1197
+                if (existConditionList.contains(tag)) {
1198
+                    existIndexList.add(i + START_LINE_NUMBER);
1199
+                } else {
1200
+                    if (repeatList.contains(tag)) {
1201
+                        existIndexList.add(i + START_LINE_NUMBER);
1202
+                    } else {
1203
+                        repeatList.add(tag);
1204
+                        skipNum++;
1205
+                    }
1206
+                }
1207
+            }
1208
+            if (CollUtil.isNotEmpty(existIndexList)) {
1209
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
1210
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
1211
+            }
1212
+        }
999 1213
         rewardApprovalService.batchInsert(list);
1000
-        return list.size();
1214
+        return ImportResultDto.builder().importNum(list.size()).build();
1001 1215
     }
1002 1216
 
1003 1217
     /** 13. 部门奖惩记录表 → ledger_reward_penalty
@@ -1027,7 +1241,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
1027 1241
      * R2: 姓名(0) 时间(起)(1) 时间(止)(2) 休假类别(3) 天数/时长(4)
1028 1242
      * 天数/时长列可能是纯数字(天)或"X小时"格式;小时值按8小时/天换算成天数
1029 1243
      */
1030
-    private int doLeaveSpecial(Sheet sheet, String batchNo, String username) {
1244
+    private ImportResultDto doLeaveSpecial(Sheet sheet, String batchNo, String username) {
1031 1245
         List<LedgerLeaveSpecial> list = new ArrayList<>();
1032 1246
         for (Object[] c : dataRows(sheet, 2)) {
1033 1247
             LedgerLeaveSpecial o = new LedgerLeaveSpecial();
@@ -1057,8 +1271,33 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
1057 1271
             o.setCreateBy(username);
1058 1272
             list.add(o);
1059 1273
         }
1274
+        if (CollUtil.isNotEmpty(list)) {
1275
+            List<LedgerLeaveSpecial> existList = leaveSpecialService.selectList(new LedgerLeaveSpecial());
1276
+            List<String> repeatList = new ArrayList<>();
1277
+            Integer skipNum = 0;
1278
+            List<Integer> existIndexList = new ArrayList<>();
1279
+            List<String> existConditionList = existList.stream().map(item -> item.getPersonName() + "_" + item.getStartDate() + "_" + item.getEndDate()).collect(Collectors.toList());
1280
+            for (int i = 0; i < list.size(); i++) {
1281
+                LedgerLeaveSpecial item = list.get(i);
1282
+                String tag = item.getPersonName() + "_" + item.getStartDate() + "_" + item.getEndDate();
1283
+                if (existConditionList.contains(tag)) {
1284
+                    existIndexList.add(i + START_LINE_NUMBER);
1285
+                } else {
1286
+                    if (repeatList.contains(tag)) {
1287
+                        existIndexList.add(i + START_LINE_NUMBER);
1288
+                    } else {
1289
+                        repeatList.add(tag);
1290
+                        skipNum++;
1291
+                    }
1292
+                }
1293
+            }
1294
+            if (CollUtil.isNotEmpty(existIndexList)) {
1295
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
1296
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
1297
+            }
1298
+        }
1060 1299
         leaveSpecialService.batchInsert(list);
1061
-        return list.size();
1300
+        return ImportResultDto.builder().importNum(list.size()).build();
1062 1301
     }
1063 1302
 
1064 1303
     /** 15. 锦旗及感谢信 → ledger_banner_letter
@@ -1741,7 +1980,7 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
1741 1980
      * 导入顺序:姓名(0) 一级发证时间(1) 二级发证时间(2) 三级发证时间(3)
1742 1981
      *          四级发证时间(4) 五级发证时间(5)
1743 1982
      */
1744
-    private int doQualificationLevel(Sheet sheet, String batchNo, String username) {
1983
+    private ImportResultDto doQualificationLevel(Sheet sheet, String batchNo, String username) {
1745 1984
         List<LedgerQualificationLevel> list = new ArrayList<>();
1746 1985
         for (Object[] c : dataRows(sheet, 2)) {
1747 1986
             LedgerQualificationLevel o = new LedgerQualificationLevel();
@@ -1773,7 +2012,32 @@ public class LedgerCombinedImportServiceImpl implements ILedgerCombinedImportSer
1773 2012
             o.setCreateBy(username);
1774 2013
             list.add(o);
1775 2014
         }
2015
+        if (CollUtil.isNotEmpty(list)) {
2016
+            List<LedgerQualificationLevel> existList = qualificationLevelService.selectQueryList(new LedgerQualificationLevel());
2017
+            List<String> repeatList = new ArrayList<>();
2018
+            Integer skipNum = 0;
2019
+            List<Integer> existIndexList = new ArrayList<>();
2020
+            List<String> existConditionList = existList.stream().map(item -> item.getPersonName()).collect(Collectors.toList());
2021
+            for (int i = 0; i < list.size(); i++) {
2022
+                LedgerQualificationLevel item = list.get(i);
2023
+                String tag = item.getPersonName();
2024
+                if (existConditionList.contains(tag)) {
2025
+                    existIndexList.add(i + START_LINE_NUMBER);
2026
+                } else {
2027
+                    if (repeatList.contains(tag)) {
2028
+                        existIndexList.add(i + START_LINE_NUMBER);
2029
+                    } else {
2030
+                        repeatList.add(tag);
2031
+                        skipNum++;
2032
+                    }
2033
+                }
2034
+            }
2035
+            if (CollUtil.isNotEmpty(existIndexList)) {
2036
+                String repeatNum = existIndexList.stream().map(Object::toString).collect(Collectors.joining("、"));
2037
+                return ImportResultDto.builder().importNum(0).skipNum(skipNum).repeatNumDesc(repeatNum).build();
2038
+            }
2039
+        }
1776 2040
         qualificationLevelService.batchInsert(list);
1777
-        return list.size();
2041
+        return ImportResultDto.builder().importNum(list.size()).build();
1778 2042
     }
1779 2043
 }