瀏覽代碼

nzy导入功能

liutao 2 周之前
父節點
當前提交
748d3d1b0d

+ 17 - 0
YHYZT/server/src/main/java/com/zjugis/yzt/controller/BaseRestController.java

@@ -111,6 +111,23 @@ public class BaseRestController extends BaseLogger {
         return result;
     }
 
+    /**
+     * error result with data
+     *
+     * @param message   错误信息
+     * @param errorCode 错误代码
+     * @param data      附加数据(如错误列表等)
+     * @return
+     */
+    protected Map error(String message, ErrorCode errorCode, Object data) {
+        Map<String, Object> result = new HashMap();
+        result.put(Result.success.name(), false);
+        result.put(Result.code.name(), errorCode.getCode());
+        result.put(Result.message.name(), message);
+        result.put(Result.data.name(), data);
+        return result;
+    }
+
     /**
      * send file
      *

+ 9 - 3
YHYZT/server/src/main/java/com/zjugis/yzt/controller/StNzydkController.java

@@ -14,6 +14,7 @@ import java.util.stream.Collectors;
 import java.util.Comparator;
 import java.util.ArrayList;
 import java.util.Optional;
+import java.util.Map;
 
 /**
  * @program: yh_yzt
@@ -23,7 +24,7 @@ import java.util.Optional;
  **/
 @RestController
 @RequestMapping("/api/stnzy")
-public class StNzydkController {
+public class StNzydkController extends BaseRestController {
 
     @Autowired
     private StNzydkService stNzydkService;
@@ -134,8 +135,13 @@ public class StNzydkController {
      * @return
      */
     @PostMapping("/upload")
-    public boolean uploadStNzydkData(@RequestParam("file") MultipartFile file) {
-        return stNzydkService.uploadNzydkData(file);
+    public Map uploadStNzydkData(@RequestParam("file") MultipartFile file) {
+        List<String> errorList = stNzydkService.uploadNzydkData(file);
+        if (errorList == null || errorList.isEmpty()) {
+            return result(true);
+        } else {
+            return error("部分数据导入失败", ErrorCode.DEFAULT, errorList);
+        }
     }
 
     /**

+ 3 - 1
YHYZT/server/src/main/java/com/zjugis/yzt/service/StNzydkService.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.zjugis.yzt.beans.entity.StNzydk;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.List;
+
 /**
  * @program: yh_yzt
  * @description: 农转用地块Service
@@ -11,5 +13,5 @@ import org.springframework.web.multipart.MultipartFile;
  * @create: 2024-10-11 14:45
  **/
 public interface StNzydkService extends IService<StNzydk> {
-    boolean uploadNzydkData(MultipartFile zipFile);
+    List<String> uploadNzydkData(MultipartFile zipFile);
 } 

+ 110 - 88
YHYZT/server/src/main/java/com/zjugis/yzt/service/impl/StNzydkServiceImpl.java

@@ -1,26 +1,24 @@
 package com.zjugis.yzt.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.zjugis.yzt.beans.entity.StNzydk;
-import com.zjugis.yzt.dao.StGddkMapper;
 import com.zjugis.yzt.dao.StNzydkMapper;
 import com.zjugis.yzt.service.StNzydkService;
 import com.zjugis.yzt.utils.ExcelUtils;
+import com.zjugis.yzt.utils.ZipFileProcessor;
 import com.zjugis.yzt.utils.geocomm.ParseResult;
 import com.zjugis.yzt.utils.geocomm.TxtReader;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.*;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
+
 
 /**
  * @program: yh_yzt
@@ -33,68 +31,38 @@ import java.util.zip.ZipInputStream;
 public class StNzydkServiceImpl extends ServiceImpl<StNzydkMapper, StNzydk> implements StNzydkService {
 
     @Override
-    public boolean uploadNzydkData(MultipartFile zipFile) {
+    public List<String> uploadNzydkData(MultipartFile zipFile) {
+        List<String> errorList = new ArrayList<>();
         if (zipFile.isEmpty()) {
-            log.error("上传文件为空");
-            return false;
+            String msg = "上传文件为空";
+            log.error(msg);
+            errorList.add(msg);
+            return errorList;
         }
 
         File tempDir = null;
         try {
-            // 创建临时目录
-            tempDir = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());
-            System.out.println("tempDir:" + tempDir.getAbsolutePath());
-            if (!tempDir.exists()) {
-                tempDir.mkdirs();
-            }
-
-            // 解压ZIP文件
-            Map<String, File> txtFiles = new HashMap<>();
-            File xlsxFile = null;
-
-            try (ZipInputStream zis = new ZipInputStream(zipFile.getInputStream())) {
-                ZipEntry entry;
-                while ((entry = zis.getNextEntry()) != null) {
-                    File newFile = new File(tempDir, entry.getName());
-                    if (entry.isDirectory()) {
-                        newFile.mkdirs();
-                    } else {
-                        // 确保父目录存在
-                        new File(newFile.getParent()).mkdirs();
-                        try (FileOutputStream fos = new FileOutputStream(newFile)) {
-                            byte[] buffer = new byte[1024];
-                            int len;
-                            while ((len = zis.read(buffer)) > 0) {
-                                fos.write(buffer, 0, len);
-                            }
-                        }
-
-                        if (newFile.getName().toLowerCase().endsWith(".xlsx")) {
-                            xlsxFile = newFile;
-                        } else if (newFile.getName().toLowerCase().endsWith(".txt")) {
-                            String fileNameWithoutExt = newFile.getName().substring(0, newFile.getName().lastIndexOf('.'));
-                            txtFiles.put(fileNameWithoutExt, newFile);
-                        }
-                    }
-                }
-            }
-
-            if (xlsxFile == null) {
-                log.error("ZIP包中未找到XLSX文件");
-                return false;
-            }
-
+            ZipFileProcessor.ZipProcessResult zipProcessResult = ZipFileProcessor.processZipFile(zipFile);
+            Map<String, File> txtFiles = zipProcessResult.getTxtFiles();
+            File xlsxFile = zipProcessResult.getXlsxFile();
+            tempDir = zipProcessResult.getTempDir();
             // --- Start: 使用 ExcelUtils.importExcel 解析 XLSX 文件 ---
             Map<String, Map<String, Object>> batchInfoMap = new HashMap<>();
-            List<Map<String, Object>> projectInfoList = new ArrayList<>();
-
 
             int batchSheetIndex = 0;
             int projectSheetIndex = 1;
 
-            List<Map<String, Object>> batchDataList = ExcelUtils.importExcel(
-                    new FileInputStream(xlsxFile), xlsxFile.getName(), 0, 1, batchSheetIndex
-            );
+            List<Map<String, Object>> batchDataList;
+            try {
+                batchDataList = ExcelUtils.importExcel(
+                        new FileInputStream(xlsxFile), xlsxFile.getName(), 0, 1, batchSheetIndex
+                );
+            } catch (Exception e) {
+                String msg = "解析批次信息sheet失败: " + e.getMessage();
+                log.error(msg, e);
+                errorList.add(msg);
+                return errorList;
+            }
             if (!batchDataList.isEmpty()) {
                 Map<String, Object> batchData = batchDataList.get(0);
                 String pcbh = batchData.containsKey("批次索引") ? String.valueOf(batchData.get("批次索引")) : null;
@@ -102,15 +70,26 @@ public class StNzydkServiceImpl extends ServiceImpl<StNzydkMapper, StNzydk> impl
                     batchInfoMap.put(pcbh, batchData);
                 }
             } else {
-                log.warn("未能从 '农转用批次信息' sheet 读取到数据。");
+                String msg = "未能从 '农转用批次信息' sheet 读取到数据。";
+                log.warn(msg);
+                errorList.add(msg);
             }
 
-
-            projectInfoList = ExcelUtils.importExcel(
-                    new FileInputStream(xlsxFile), xlsxFile.getName(), 0, 1, projectSheetIndex
-            );
+            List<Map<String, Object>> projectInfoList;
+            try {
+                projectInfoList = ExcelUtils.importExcel(
+                        new FileInputStream(xlsxFile), xlsxFile.getName(), 0, 1, projectSheetIndex
+                );
+            } catch (Exception e) {
+                String msg = "解析项目信息sheet失败: " + e.getMessage();
+                log.error(msg, e);
+                errorList.add(msg);
+                return errorList;
+            }
             if (projectInfoList.isEmpty()) {
-                log.warn("未能从 '农转用项目信息' sheet 读取到数据。");
+                String msg = "未能从 '农转用项目信息' sheet 读取到数据。";
+                log.warn(msg);
+                errorList.add(msg);
             }
 
             // --- End: 使用 ExcelUtils.importExcel 解析 XLSX 文件 ---
@@ -130,7 +109,9 @@ public class StNzydkServiceImpl extends ServiceImpl<StNzydkMapper, StNzydk> impl
                     stNzydk.setPzMj(parseBigDecimal(batchInfo.containsKey("批次总面积(公顷)") ? String.valueOf(batchInfo.get("批次总面积(公顷)")) : null));
                     stNzydk.setNmjf(batchInfo.containsKey("是否农民建房") ? String.valueOf(batchInfo.get("是否农民建房")) : null);
                 } else {
-                    log.warn("未找到批次索引为 {} 的批次信息,项目 {} 将跳过批次信息填充。", pcbh, projectInfo.containsKey("项目编号") ? String.valueOf(projectInfo.get("项目编号")) : "未知项目");
+                    String msg = String.format("未找到批次索引为 %s 的批次信息,项目 %s 将跳过批次信息填充。", pcbh, projectInfo.containsKey("项目编号") ? String.valueOf(projectInfo.get("项目编号")) : "未知项目");
+                    log.warn(msg);
+                    errorList.add(msg);
                 }
 
                 // 项目信息
@@ -142,45 +123,61 @@ public class StNzydkServiceImpl extends ServiceImpl<StNzydkMapper, StNzydk> impl
                 stNzydk.setDkMj(parseBigDecimal(projectInfo.containsKey("项目面积(公顷)") ? String.valueOf(projectInfo.get("项目面积(公顷)")) : null));
                 stNzydk.setDkQs(projectInfo.containsKey("用地主体") ? String.valueOf(projectInfo.get("用地主体")) : null);
                 stNzydk.setBz(projectInfo.containsKey("备注") ? String.valueOf(projectInfo.get("备注")) : null);
+                // 保存到数据库前,先通过 dkBh 删除已存在的记录
+                if (stNzydk.getDkBh() != null) {
+                    // 构造查询条件
+                    QueryWrapper<StNzydk> queryWrapper = new QueryWrapper<>();
+                    queryWrapper.eq("dk_bh", stNzydk.getDkBh());
+                    // 删除已存在的记录
+                    try {
+                        this.remove(queryWrapper);
+                    } catch (Exception e) {
+                        String msg = String.format("删除项目编号为 %s 的旧数据失败: %s", stNzydk.getDkBh(), e.getMessage());
+                        log.error(msg, e);
+                        errorList.add(msg);
+                    }
+                }
                 // 保存到数据库
-                if (!this.save(stNzydk)) {
-                    log.error("保存农转用数据失败:{}", stNzydk.getDkBh());
-                    return false;
+                try {
+                    if (!this.save(stNzydk)) {
+                        String msg = String.format("保存农转用数据失败:%s", stNzydk.getDkBh());
+                        log.error(msg);
+                        errorList.add(msg);
+                        continue;
+                    }
+                } catch (Exception e) {
+                    String msg = String.format("保存农转用数据异常:%s,错误:%s", stNzydk.getDkBh(), e.getMessage());
+                    log.error(msg, e);
+                    errorList.add(msg);
+                    continue;
                 }
                 // 获取保存后的objectid
                 Integer objectId = stNzydk.getObjectid();
                 if (objectId == null) {
-                    log.error("获取保存后的objectid失败:{}", stNzydk.getDkBh());
-                    return false;
+                    String msg = String.format("获取保存后的objectid失败:%s", stNzydk.getDkBh());
+                    log.error(msg);
+                    errorList.add(msg);
+                    continue;
                 }
                 // 解析图形信息
                 String projectCode = stNzydk.getDkBh();
                 File txtFile = txtFiles.get(projectCode);
-                if (txtFile != null) {
-                    try (FileInputStream txtInputStream = new FileInputStream(txtFile)) {
-                        TxtReader txtReader = new TxtReader(txtInputStream);
-                        ParseResult parseResult = txtReader.read();
-                        if (parseResult != null && parseResult.getGeometry() != null) {
-                            String wkt = parseResult.getGeometry().toText();
-                            ((StNzydkMapper) this.baseMapper).updateShapeById(objectId, wkt, 4528);
-                        } else {
-                            log.warn("项目 {} 的TXT文件解析失败或未获取到Geometry数据。", projectCode);
-                        }
-                    } catch (Exception e) {
-                        log.error("解析项目 {} 的TXT文件失败: {}", projectCode, e.getMessage());
-                    }
-                } else {
-                    log.warn("未找到项目 {} 对应的TXT界址点文件。", projectCode);
+                try {
+                    updateShapeWithErrorList(objectId, projectCode, txtFile, errorList);
+                } catch (Exception e) {
+                    String msg = String.format("项目 %s 的TXT文件解析异常: %s", projectCode, e.getMessage());
+                    log.error(msg, e);
+                    errorList.add(msg);
                 }
-
-
             }
 
-            return true;
+            return errorList;
 
         } catch (IOException e) {
-            log.error("文件上传或处理失败", e);
-            return false;
+            String msg = "文件上传或处理失败: " + e.getMessage();
+            log.error(msg, e);
+            errorList.add(msg);
+            return errorList;
         } finally {
             // 清理临时文件
             if (tempDir != null && tempDir.exists()) {
@@ -189,6 +186,31 @@ public class StNzydkServiceImpl extends ServiceImpl<StNzydkMapper, StNzydk> impl
         }
     }
 
+    private void updateShapeWithErrorList(Integer objectId, String projectCode, File txtFile, List<String> errorList) {
+        if (txtFile != null) {
+            try (FileInputStream txtInputStream = new FileInputStream(txtFile)) {
+                TxtReader txtReader = new TxtReader(txtInputStream);
+                ParseResult parseResult = txtReader.read();
+                if (parseResult != null && parseResult.getGeometry() != null) {
+                    String wkt = parseResult.getGeometry().toText();
+                    ((StNzydkMapper) this.baseMapper).updateShapeById(objectId, wkt, 4528);
+                } else {
+                    String msg = String.format("项目 %s 的TXT文件解析失败或未获取到Geometry数据。", projectCode);
+                    log.warn(msg);
+                    errorList.add(msg);
+                }
+            } catch (Exception e) {
+                String msg = String.format("解析项目 %s 的TXT文件失败: %s", projectCode, e.getMessage());
+                log.error(msg, e);
+                errorList.add(msg);
+            }
+        } else {
+            String msg = String.format("未找到项目 %s 对应的TXT界址点文件。", projectCode);
+            log.warn(msg);
+            errorList.add(msg);
+        }
+    }
+
     private BigDecimal parseBigDecimal(String value) {
         if (value == null || value.isEmpty()) {
             return null;

+ 83 - 0
YHYZT/server/src/main/java/com/zjugis/yzt/utils/ZipFileProcessor.java

@@ -0,0 +1,83 @@
+package com.zjugis.yzt.utils;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+@Slf4j
+public class ZipFileProcessor {
+    
+    @Data
+    public static class ZipProcessResult {
+        private File tempDir;
+        private Map<String, File> txtFiles = new HashMap<>();
+        private File xlsxFile;
+    }
+    
+    public static ZipProcessResult processZipFile(MultipartFile zipFile) throws IOException {
+        ZipProcessResult result = new ZipProcessResult();
+        
+        // 创建临时目录
+        File tempDir = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());
+        log.info("创建临时目录: {}", tempDir.getAbsolutePath());
+        if (!tempDir.exists()) {
+            tempDir.mkdirs();
+        }
+        result.setTempDir(tempDir);
+        
+        // 解压ZIP文件
+        try (ZipInputStream zis = new ZipInputStream(zipFile.getInputStream())) {
+            ZipEntry entry;
+            while ((entry = zis.getNextEntry()) != null) {
+                File newFile = new File(tempDir, entry.getName());
+                if (entry.isDirectory()) {
+                    newFile.mkdirs();
+                } else {
+                    // 确保父目录存在
+                    new File(newFile.getParent()).mkdirs();
+                    try (FileOutputStream fos = new FileOutputStream(newFile)) {
+                        byte[] buffer = new byte[1024];
+                        int len;
+                        while ((len = zis.read(buffer)) > 0) {
+                            fos.write(buffer, 0, len);
+                        }
+                    }
+
+                    if (newFile.getName().toLowerCase().endsWith(".xlsx")) {
+                        result.setXlsxFile(newFile);
+                    } else if (newFile.getName().toLowerCase().endsWith(".txt")) {
+                        String fileNameWithoutExt = newFile.getName().substring(0, newFile.getName().lastIndexOf('.'));
+                        result.getTxtFiles().put(fileNameWithoutExt, newFile);
+                    }
+                }
+            }
+        }
+        
+        return result;
+    }
+    
+    public static void cleanupTempDir(File tempDir) {
+        if (tempDir != null && tempDir.exists()) {
+            deleteDirectory(tempDir);
+        }
+    }
+    
+    private static void deleteDirectory(File directory) {
+        File[] allContents = directory.listFiles();
+        if (allContents != null) {
+            for (File file : allContents) {
+                deleteDirectory(file);
+            }
+        }
+        directory.delete();
+    }
+}