| | |
| | | package com.ard.inspection.service.impl; |
| | | |
| | | import com.ard.common.core.domain.AjaxResult; |
| | | import com.ard.common.utils.uuid.IdUtils; |
| | | import com.ard.inspection.domain.ArdPointCloud; |
| | | import com.ard.inspection.domain.UploadFileEntity; |
| | | import com.ard.inspection.service.IArdPointCloudService; |
| | | import com.ard.inspection.service.IBigFileUploadService; |
| | | import com.ard.inspection.utils.ZipFileUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.io.RandomAccessFile; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static com.ard.inspection.utils.ZipFileUtils.formatFileSize; |
| | | |
| | | /** |
| | | * @author xia |
| | |
| | | @Service |
| | | @Slf4j |
| | | public class BigFileUploadServiceImpl implements IBigFileUploadService { |
| | | |
| | | public static final String CLOUD_FILE_PATH = "http://192.168.1.3:6100"; |
| | | |
| | | @Autowired |
| | | private IArdPointCloudService ardPointCloudService; |
| | | |
| | | @Resource |
| | | private ZipFileUtils zipFileUtils; |
| | | |
| | | @Override |
| | | public Map<String, Object> checkChunk(String fileMd5,String chunkPath) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> uploadChunk(MultipartFile file,UploadFileEntity uploadFileEntity,String chunkPath) { |
| | | Map<String, Object> result = new HashMap<>(); |
| | | try { |
| | | // 验证参数 |
| | | if (file.isEmpty()) { |
| | | result.put("exception", "文件不能为空!!!"); |
| | | return result; |
| | | } |
| | | |
| | | // 创建分片目录 |
| | | String chunkDirPath = chunkPath + File.separator + uploadFileEntity.getFileMd5(); |
| | | File chunkDir = new File(chunkDirPath); |
| | | if (!chunkDir.exists()) { |
| | | chunkDir.mkdirs(); |
| | | } |
| | | |
| | | // 保存分片 |
| | | String chunkFileName = uploadFileEntity.getChunkNumber() + ".part"; |
| | | File chunkFile = new File(chunkDir, chunkFileName); |
| | | file.transferTo(chunkFile); |
| | | |
| | | result.put("message", "分片上传成功!!!"); |
| | | return result; |
| | | } catch (IOException e) { |
| | | log.error("分片上传失败", e); |
| | | result.put("exception", "分片上传失败!!!"); |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> mergeChunks(String md5,String fileName,String uploadPath) { |
| | | Map<String, Object> result = new HashMap<>(); |
| | | // 临时目录 |
| | |
| | | |
| | | // 这里可以保存文件信息到数据库,例如文件路径、文件名、md5等 |
| | | // fileService.saveFileInfo(...); |
| | | // ArdPointCloud ardPointCloud = new ArdPointCloud(); |
| | | // ardPointCloud.setFileName(newFileName); |
| | | // ardPointCloud.setFileSize(mergeFile.length()); |
| | | // ardPointCloud.setAssociatedState("0"); |
| | | // ardPointCloudService.insertArdPointCloud(ardPointCloud); |
| | | |
| | | result.put("message", "文件合并成功"); |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 大文件上传并解压接口 |
| | | * @param file 上传的ZIP文件 |
| | | * @param overwrite 是否覆盖已存在文件(默认false) |
| | | * @param uploadPath 上传文件存储路径 |
| | | * @param chunkPath 临时切片存储路径 |
| | | * @param zipPath 解压文件存储路径 |
| | | * @return 上传结果 |
| | | */ |
| | | @Override |
| | | public AjaxResult uploadBigZipFile(MultipartFile file, boolean overwrite, |
| | | String uploadPath, |
| | | String chunkPath, |
| | | String zipPath) { |
| | | // 1. 校验文件是否为空 |
| | | if (file.isEmpty()) { |
| | | return AjaxResult.error("上传文件不能为空"); |
| | | } |
| | | |
| | | // 2. 校验文件格式 |
| | | String originalFilename = file.getOriginalFilename(); |
| | | if (originalFilename == null || !originalFilename.endsWith(".zip")) { |
| | | return AjaxResult.error("仅支持ZIP格式文件上传"); |
| | | } |
| | | |
| | | // 2.1 校验文件名是否重复 |
| | | if (!overwrite) { |
| | | if (ardPointCloudService.selectArdPointCloudByFileName(originalFilename) != null) { |
| | | return AjaxResult.error("文件已存在"); |
| | | } |
| | | } |
| | | |
| | | // 3. 创建临时目录 |
| | | File tempDir = new File(uploadPath); |
| | | if (!tempDir.exists()) { |
| | | boolean mkdirs = tempDir.mkdirs(); |
| | | if (!mkdirs) { |
| | | return AjaxResult.error("创建临时上传目录失败"); |
| | | } |
| | | } |
| | | |
| | | // 4. 保存上传的ZIP文件到临时目录(避免重名) |
| | | String tempFileName = UUID.randomUUID() + ".zip"; |
| | | File tempFile = new File(chunkPath + File.separator + tempFileName); |
| | | try { |
| | | file.transferTo(tempFile); |
| | | log.info("临时文件保存成功:{},文件大小:{}MB", tempFile.getAbsolutePath(), |
| | | file.getSize() / 1024 / 1024); |
| | | } catch (IOException e) { |
| | | log.error("保存临时文件失败", e); |
| | | return AjaxResult.error("文件上传失败:" + e.getMessage()); |
| | | } |
| | | |
| | | // 5. 解压文件 |
| | | try { |
| | | zipFileUtils.unzip(tempFile.getAbsolutePath(), overwrite); |
| | | // 6. 删除临时文件(可选,若需要保留压缩包可注释) |
| | | boolean delete = tempFile.delete(); |
| | | if (delete) { |
| | | log.info("临时文件已删除:{}", tempFile.getAbsolutePath()); |
| | | } |
| | | ArdPointCloud ardPointCloud = new ArdPointCloud(); |
| | | ardPointCloud.setFileName(originalFilename); |
| | | ardPointCloud.setFileSize(formatFileSize(file.getSize())); |
| | | int dotIndex = originalFilename.lastIndexOf('.'); |
| | | String folderName = (dotIndex > 0) ? originalFilename.substring(0, dotIndex) : originalFilename; |
| | | ardPointCloud.setFolderName(folderName); |
| | | String zipP = CLOUD_FILE_PATH + zipPath + "/" + folderName + "/tileset.json"; |
| | | ardPointCloud.setFilePath(zipP); |
| | | return AjaxResult.success("文件上传并解压成功", ardPointCloud); |
| | | } catch (IOException e) { |
| | | log.error("解压文件失败", e); |
| | | // 失败时删除临时文件 |
| | | if (tempFile.exists()) { |
| | | tempFile.delete(); |
| | | } |
| | | return AjaxResult.error("文件解压失败:" + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | } |