فهرست منبع

优化巡检记录导出

hanzhengyi 1 روز پیش
والد
کامیت
d2c76e7653

+ 148 - 25
service-fire/service-fire-biz/src/main/java/com/usky/fire/service/impl/PatrolInspectionRecordServiceImpl.java

@@ -426,7 +426,7 @@ public class PatrolInspectionRecordServiceImpl extends AbstractCrudService<Patro
     }
 
     /**
-     * 导出巡检记录
+     * 导出巡检记录(优化版:使用批量查询避免N+1问题)
      * @param areaName
      * @param siteName
      * @param name
@@ -466,34 +466,157 @@ public class PatrolInspectionRecordServiceImpl extends AbstractCrudService<Patro
         }
         queryWrapper.orderByDesc(PatrolInspectionRecord::getId);
         List<PatrolInspectionRecord> patrolInspectionRecordList = this.list(queryWrapper);
+        
+        if (patrolInspectionRecordList.isEmpty()) {
+            return new ArrayList<>();
+        }
+        
+        // 提取所有记录ID
+        List<Integer> recordIds = new ArrayList<>();
+        for (PatrolInspectionRecord record : patrolInspectionRecordList) {
+            recordIds.add(record.getId());
+        }
+        
+        // 批量查询所有相关数据,避免N+1查询问题
+        // 1. 批量查询所有记录选项
+        LambdaQueryWrapper<PatrolInspectionRecordOption> recordOptionWrapper = Wrappers.lambdaQuery();
+        recordOptionWrapper.in(PatrolInspectionRecordOption::getRecordId, recordIds)
+                .orderByAsc(PatrolInspectionRecordOption::getRecordId)
+                .orderByAsc(PatrolInspectionRecordOption::getId);
+        List<PatrolInspectionRecordOption> allRecordOptions = patrolInspectionRecordOptionMapper.selectList(recordOptionWrapper);
+        
+        // 2. 批量查询所有图片
+        LambdaQueryWrapper<PatrolInspectionRecordPicture> pictureWrapper = Wrappers.lambdaQuery();
+        pictureWrapper.select(PatrolInspectionRecordPicture::getPictureUrl, PatrolInspectionRecordPicture::getRecordId)
+                .in(PatrolInspectionRecordPicture::getRecordId, recordIds)
+                .orderByAsc(PatrolInspectionRecordPicture::getRecordId);
+        List<PatrolInspectionRecordPicture> allPictures = orphansInspectionRecordPictureMapper.selectList(pictureWrapper);
+        
+        // 构建缓存Map:recordId -> List<PatrolInspectionRecordOption>
+        Map<Integer, List<PatrolInspectionRecordOption>> recordOptionMap = new HashMap<>();
+        for (PatrolInspectionRecordOption option : allRecordOptions) {
+            recordOptionMap.computeIfAbsent(option.getRecordId(), k -> new ArrayList<>()).add(option);
+        }
+        
+        // 构建缓存Map:recordId -> List<PatrolInspectionRecordPicture>
+        Map<Integer, List<PatrolInspectionRecordPicture>> pictureMap = new HashMap<>();
+        for (PatrolInspectionRecordPicture picture : allPictures) {
+            pictureMap.computeIfAbsent(picture.getRecordId(), k -> new ArrayList<>()).add(picture);
+        }
+        
+        // 收集所有需要查询的contentId和contentOptionId
+        List<Integer> allContentIds = new ArrayList<>();
+        List<Integer> allContentOptionIds = new ArrayList<>();
+        for (PatrolInspectionRecordOption option : allRecordOptions) {
+            if (option.getContentId() != null) {
+                allContentIds.add(option.getContentId());
+            }
+            if (option.getContentOptionId() != null && !" ".equals(option.getContentOptionId())) {
+                allContentOptionIds.add(option.getContentOptionId());
+            }
+        }
+        
+        // 3. 批量查询所有内容
+        Map<Integer, PatrolInspectionContent> contentMap = new HashMap<>();
+        if (!allContentIds.isEmpty()) {
+            LambdaQueryWrapper<PatrolInspectionContent> contentWrapper = Wrappers.lambdaQuery();
+            contentWrapper.in(PatrolInspectionContent::getId, allContentIds)
+                    .orderByAsc(PatrolInspectionContent::getId);
+            List<PatrolInspectionContent> allContents = patrolInspectionContentMapper.selectList(contentWrapper);
+            for (PatrolInspectionContent content : allContents) {
+                contentMap.put(content.getId(), content);
+            }
+        }
+        
+        // 4. 批量查询所有内容选项
+        Map<Integer, PatrolInspectionContentOption> contentOptionMap = new HashMap<>();
+        if (!allContentOptionIds.isEmpty()) {
+            LambdaQueryWrapper<PatrolInspectionContentOption> contentOptionWrapper = Wrappers.lambdaQuery();
+            contentOptionWrapper.in(PatrolInspectionContentOption::getId, allContentOptionIds)
+                    .orderByAsc(PatrolInspectionContentOption::getId);
+            List<PatrolInspectionContentOption> allContentOptions = patrolInspectionContentOptionMapper.selectList(contentOptionWrapper);
+            for (PatrolInspectionContentOption option : allContentOptions) {
+                contentOptionMap.put(option.getId(), option);
+            }
+        }
+        
+        // 构建结果列表
         List<PatrolInspectionRecordExportVo> list = new ArrayList<>();
         for (int i = 0; i < patrolInspectionRecordList.size(); i++) {
+            PatrolInspectionRecord record = patrolInspectionRecordList.get(i);
+            Integer recordId = record.getId();
+            
             PatrolInspectionRecordExportVo patrolInspectionRecordExportVo = new PatrolInspectionRecordExportVo();
             patrolInspectionRecordExportVo.setXh(i + 1);
-            patrolInspectionRecordExportVo.setId(patrolInspectionRecordList.get(i).getId());
-            patrolInspectionRecordExportVo.setSiteNubmber(patrolInspectionRecordList.get(i).getSiteNubmber());
-            patrolInspectionRecordExportVo.setSiteType(patrolInspectionRecordList.get(i).getSiteType());
-            patrolInspectionRecordExportVo.setAreaName(patrolInspectionRecordList.get(i).getAreaName());
-            patrolInspectionRecordExportVo.setSiteName(patrolInspectionRecordList.get(i).getSiteName());
-            patrolInspectionRecordExportVo.setName(patrolInspectionRecordList.get(i).getName());
-            patrolInspectionRecordExportVo.setPhone(patrolInspectionRecordList.get(i).getPhone());
-            patrolInspectionRecordExportVo.setPlanType(patrolInspectionRecordList.get(i).getPlanType());
-            patrolInspectionRecordExportVo.setLongitude(patrolInspectionRecordList.get(i).getLongitude());
-            patrolInspectionRecordExportVo.setLatitude(patrolInspectionRecordList.get(i).getLatitude());
-            patrolInspectionRecordExportVo.setStartDate(patrolInspectionRecordList.get(i).getStartDate().format(df));
-            patrolInspectionRecordExportVo.setEndDate(patrolInspectionRecordList.get(i).getEndDate().format(df));
-            patrolInspectionRecordExportVo.setCreateTime(patrolInspectionRecordList.get(i).getCreateTime().format(df));
-            patrolInspectionRecordExportVo.setRemarks(patrolInspectionRecordList.get(i).getRemarks());
-
-            patrolInspectionRecordExportVo.setContentTitle(getContentTitle(patrolInspectionRecordList.get(i).getId()));
-            patrolInspectionRecordExportVo.setSubmissionMethod(getSubmissionMethod(patrolInspectionRecordList.get(i).getId()));
-            patrolInspectionRecordExportVo.setOptionName(getOptionName(patrolInspectionRecordList.get(i).getId()));
-            patrolInspectionRecordExportVo.setContentRemarks(getRemarks(patrolInspectionRecordList.get(i).getId()));
-            LambdaQueryWrapper<PatrolInspectionRecordPicture> queryWrapperImage = Wrappers.lambdaQuery();//导出图片
-            queryWrapperImage.select(PatrolInspectionRecordPicture::getPictureUrl)
-                    .eq(PatrolInspectionRecordPicture::getRecordId, patrolInspectionRecordList.get(i).getId());
-            List<PatrolInspectionRecordPicture> pictures = orphansInspectionRecordPictureMapper.selectList(queryWrapperImage);
-            if (pictures.size() > 0) {
+            patrolInspectionRecordExportVo.setId(record.getId());
+            patrolInspectionRecordExportVo.setSiteNubmber(record.getSiteNubmber());
+            patrolInspectionRecordExportVo.setSiteType(record.getSiteType());
+            patrolInspectionRecordExportVo.setAreaName(record.getAreaName());
+            patrolInspectionRecordExportVo.setSiteName(record.getSiteName());
+            patrolInspectionRecordExportVo.setName(record.getName());
+            patrolInspectionRecordExportVo.setPhone(record.getPhone());
+            patrolInspectionRecordExportVo.setPlanType(record.getPlanType());
+            patrolInspectionRecordExportVo.setLongitude(record.getLongitude());
+            patrolInspectionRecordExportVo.setLatitude(record.getLatitude());
+            patrolInspectionRecordExportVo.setStartDate(record.getStartDate().format(df));
+            patrolInspectionRecordExportVo.setEndDate(record.getEndDate().format(df));
+            patrolInspectionRecordExportVo.setCreateTime(record.getCreateTime().format(df));
+            patrolInspectionRecordExportVo.setRemarks(record.getRemarks());
+
+            // 从缓存中获取数据,而不是单独查询
+            List<PatrolInspectionRecordOption> recordOptions = recordOptionMap.getOrDefault(recordId, new ArrayList<>());
+            
+            // 获取内容标题和提交方法
+            List<String> contentTitleList = new ArrayList<>();
+            List<String> submissionMethodList = new ArrayList<>();
+            List<String> optionNameList = new ArrayList<>();
+            List<String> remarksList = new ArrayList<>();
+            
+            for (PatrolInspectionRecordOption option : recordOptions) {
+                // 获取备注
+                if (option.getRemarks() != null) {
+                    remarksList.add(option.getRemarks());
+                } else {
+                    remarksList.add("");
+                }
+                
+                // 获取内容标题和提交方法
+                if (option.getContentId() != null) {
+                    PatrolInspectionContent content = contentMap.get(option.getContentId());
+                    if (content != null) {
+                        contentTitleList.add(content.getContentTitle());
+                        switch (content.getSubmissionMethod()) {
+                            case 1:
+                                submissionMethodList.add("多选");
+                                break;
+                            case 2:
+                                submissionMethodList.add("单选");
+                                break;
+                            default:
+                                submissionMethodList.add("输入框");
+                        }
+                    }
+                }
+                
+                // 获取选项名称
+                if (option.getContentOptionId() == null || " ".equals(option.getContentOptionId())) {
+                    optionNameList.add(option.getContent());
+                } else {
+                    PatrolInspectionContentOption contentOption = contentOptionMap.get(option.getContentOptionId());
+                    if (contentOption != null) {
+                        optionNameList.add(contentOption.getOptionName());
+                    }
+                }
+            }
+            
+            patrolInspectionRecordExportVo.setContentTitle(contentTitleList);
+            patrolInspectionRecordExportVo.setSubmissionMethod(submissionMethodList);
+            patrolInspectionRecordExportVo.setOptionName(optionNameList);
+            patrolInspectionRecordExportVo.setContentRemarks(remarksList);
+            
+            // 从缓存中获取图片
+            List<PatrolInspectionRecordPicture> pictures = pictureMap.getOrDefault(recordId, new ArrayList<>());
+            if (!pictures.isEmpty()) {
                 for (int j = 0; j < pictures.size() && j < 5; j++) {
                     String pictureUrl = pictures.get(j).getPictureUrl();
                     switch (j) {

+ 20 - 2
service-fire/service-fire-biz/src/main/java/com/usky/fire/service/util/ExcelUtilImage.java

@@ -85,6 +85,8 @@ public class ExcelUtilImage<T> {
     private Map<Integer, Double> statistics = new HashMap();
     private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
     public Class<T> clazz;
+    // 图片缓存:避免重复下载相同图片
+    private Map<String, byte[]> imageCache = new HashMap<>();
 
     public ExcelUtilImage(Class<T> clazz) {
         this.clazz = clazz;
@@ -274,6 +276,8 @@ public class ExcelUtilImage<T> {
             log.error("导出Excel异常{}", var6.getMessage());
         } finally {
             IOUtils.closeQuietly(this.wb);
+            // 清理图片缓存
+            this.imageCache.clear();
         }
 
     }
@@ -431,8 +435,22 @@ public class ExcelUtilImage<T> {
             ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
             String imagePath = Convert.toStr(value);
             if (StringUtils.isNotEmpty(imagePath)) {
-                byte[] data = ImageUtils.getImage(imagePath);
-                getDrawingPatriarch(cell.getSheet()).createPicture(anchor, cell.getSheet().getWorkbook().addPicture(data, this.getImageType(data)));
+                // 使用缓存避免重复下载相同图片
+                byte[] data = imageCache.get(imagePath);
+                if (data == null) {
+                    try {
+                        data = ImageUtils.getImage(imagePath);
+                        if (data != null) {
+                            imageCache.put(imagePath, data);
+                        }
+                    } catch (Exception e) {
+                        log.warn("获取图片失败: {}", imagePath, e);
+                        return;
+                    }
+                }
+                if (data != null) {
+                    getDrawingPatriarch(cell.getSheet()).createPicture(anchor, cell.getSheet().getWorkbook().addPicture(data, this.getImageType(data)));
+                }
             }
         }