1. 大文件上传并解压接口业务优化
2. 优化精细化巡检分组权限管理
3. 优化点云文件权限管理
4. 上传到服务器点云文件
3 files added
15 files modified
| | |
| | | * 查询精细化巡检分组列表 |
| | | */ |
| | | @ApiOperation("查询精细化巡检分组列表") |
| | | @PreAuthorize("@ss.hasPermi('inspection:group:list')") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:group:list')") |
| | | @GetMapping("/list") |
| | | public AjaxResult list(ArdInspectionGroup ardInspectionGroup) { |
| | | List<ArdInspectionGroup> list = ardInspectionGroupService.selectArdInspectionGroupList(ardInspectionGroup); |
| | |
| | | * 获取精细化巡检分组详细信息 |
| | | */ |
| | | @ApiOperation("获取精细化巡检分组详细信息") |
| | | @PreAuthorize("@ss.hasPermi('inspection:group:query')") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:group:query')") |
| | | @GetMapping(value = "/{groupId}") |
| | | public AjaxResult getInfo(@PathVariable("groupId") Long groupId) { |
| | | //ardInspectionGroupService.checkInspectionGroupDataScope(groupId); |
| | |
| | | * 新增精细化巡检分组 |
| | | */ |
| | | @ApiOperation("新增精细化巡检分组") |
| | | @PreAuthorize("@ss.hasPermi('inspection:group:add')") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:group:add')") |
| | | @Log(title = "精细化巡检分组", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public AjaxResult add(@RequestBody ArdInspectionGroup ardInspectionGroup) { |
| | |
| | | * 修改精细化巡检分组 |
| | | */ |
| | | @ApiOperation("修改精细化巡检分组") |
| | | @PreAuthorize("@ss.hasPermi('inspection:group:edit')") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:group:edit')") |
| | | @Log(title = "精细化巡检分组", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public AjaxResult edit(@RequestBody ArdInspectionGroup ardInspectionGroup) { |
| | |
| | | * 删除精细化巡检分组 |
| | | */ |
| | | @ApiOperation("删除精细化巡检分组") |
| | | @PreAuthorize("@ss.hasPermi('inspection:group:remove')") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:group:remove')") |
| | | @Log(title = "精细化巡检分组", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{groupId}") |
| | | public AjaxResult remove(@PathVariable Long groupId) { |
| | |
| | | * 获取巡检分组树列表 |
| | | */ |
| | | @ApiOperation("获取巡检分组树列表") |
| | | @PreAuthorize("@ss.hasPermi('inspection:group:groupTree')") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:group:groupTree')") |
| | | @GetMapping("/groupTree") |
| | | public AjaxResult deptTree(ArdInspectionGroup ardInspectionGroup) { |
| | | return success(ardInspectionGroupService.selectGroupTreeList(ardInspectionGroup)); |
| | |
| | | import com.ard.common.enums.BusinessType; |
| | | import com.ard.common.utils.poi.ExcelUtil; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | /** |
| | | * 查询点云文件列表 |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('inspection:cloud:list')") |
| | | @ApiOperation("查询点云文件列表") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:cloud:list')") |
| | | @GetMapping("/list") |
| | | public TableDataInfo list(ArdPointCloud ardPointCloud) { |
| | | startPage(); |
| | |
| | | /** |
| | | * 导出点云文件列表 |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('inspection:cloud:export')") |
| | | @ApiOperation("导出点云文件列表") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:cloud:export')") |
| | | @Log(title = "点云文件", businessType = BusinessType.EXPORT) |
| | | @PostMapping("/export") |
| | | public void export(HttpServletResponse response, ArdPointCloud ardPointCloud) { |
| | |
| | | /** |
| | | * 获取点云文件详细信息 |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('inspection:cloud:query')") |
| | | @ApiOperation("获取点云文件详细信息") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:cloud:query')") |
| | | @GetMapping(value = "/{id}") |
| | | public AjaxResult getInfo(@PathVariable("id") String id) { |
| | | return success(ardPointCloudService.selectArdPointCloudById(id)); |
| | |
| | | /** |
| | | * 新增点云文件 |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('inspection:cloud:add')") |
| | | @ApiOperation("新增点云文件") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:cloud:add')") |
| | | @Log(title = "点云文件", businessType = BusinessType.INSERT) |
| | | @PostMapping |
| | | public AjaxResult add(@RequestBody ArdPointCloud ardPointCloud) { |
| | | ardPointCloud.setCreateBy(getUsername()); |
| | | return toAjax(ardPointCloudService.insertArdPointCloud(ardPointCloud)); |
| | | } |
| | | |
| | | /** |
| | | * 修改点云文件 |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('inspection:cloud:edit')") |
| | | @ApiOperation("修改点云文件") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:cloud:edit')") |
| | | @Log(title = "点云文件", businessType = BusinessType.UPDATE) |
| | | @PutMapping |
| | | public AjaxResult edit(@RequestBody ArdPointCloud ardPointCloud) { |
| | | ardPointCloud.setUpdateBy(getUsername()); |
| | | return toAjax(ardPointCloudService.updateArdPointCloud(ardPointCloud)); |
| | | } |
| | | |
| | | /** |
| | | * 删除点云文件 |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('inspection:cloud:remove')") |
| | | @ApiOperation("删除点云文件") |
| | | //@PreAuthorize("@ss.hasPermi('inspection:cloud:remove')") |
| | | @Log(title = "点云文件", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{ids}") |
| | | public AjaxResult remove(@PathVariable String[] ids) { |
| | |
| | | import com.ard.common.core.controller.BaseController; |
| | | import com.ard.common.core.domain.AjaxResult; |
| | | import com.ard.common.enums.BusinessType; |
| | | import com.ard.inspection.domain.UploadFileEntity; |
| | | import com.ard.inspection.service.IBigFileUploadService; |
| | | import com.ard.inspection.utils.ZipFileUtils; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.*; |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * @author xia |
| | |
| | | @Value(value = "${inspection.chunk.path}") |
| | | private String chunkPath; |
| | | |
| | | @Value(value = "${inspection.chunk.zipPath}") |
| | | private String zipPath; |
| | | |
| | | /** |
| | | * 检查分片是否存在 |
| | | */ |
| | |
| | | */ |
| | | @ApiOperation("上传分片") |
| | | @PostMapping("/bigfile/chunk") |
| | | public AjaxResult uploadChunk(@RequestParam("file") MultipartFile file, |
| | | @RequestParam("chunkNumber") Integer chunkNumber, |
| | | @RequestParam("fileMd5") String fileMd5) { |
| | | Map<String, Object> result = bigFileUploadService.uploadChunk(file, chunkNumber, fileMd5, chunkPath); |
| | | public AjaxResult uploadChunk(@RequestBody UploadFileEntity uploadFileEntity, |
| | | @RequestParam("file") MultipartFile file) { |
| | | // public AjaxResult uploadChunk(@RequestParam("file") MultipartFile file, |
| | | // @RequestParam("chunkNumber") Integer chunkNumber, |
| | | // @RequestParam("fileMd5") String fileMd5) { |
| | | Map<String, Object> result = bigFileUploadService.uploadChunk(file,uploadFileEntity,chunkPath); |
| | | return AjaxResult.success(result); |
| | | } |
| | | |
| | |
| | | return AjaxResult.success(result); |
| | | } |
| | | |
| | | /** |
| | | * 大文件上传并解压接口 |
| | | * @param file 上传的ZIP文件 |
| | | * @param overwrite 是否覆盖已存在文件(默认false) |
| | | * @return 上传结果 |
| | | */ |
| | | @ApiOperation("大文件上传并解压接口") |
| | | @Log(title = "大文件上传解压", businessType = BusinessType.INSERT) |
| | | @PostMapping("/upload/bigFileUnzip") |
| | | public AjaxResult uploadBigZipFile( |
| | | @RequestPart("file") MultipartFile file) { |
| | | //@RequestParam(value = "overwrite", defaultValue = "false") boolean overwrite) { |
| | | boolean overwrite = false; |
| | | return bigFileUploadService.uploadBigZipFile(file,overwrite,uploadPath,chunkPath,zipPath); |
| | | } |
| | | |
| | | } |
| | |
| | | servlet: |
| | | multipart: |
| | | # 单个文件大小 |
| | | max-file-size: 10MB |
| | | max-file-size: 3GB |
| | | # 设置总上传的文件大小 |
| | | max-request-size: 20MB |
| | | max-request-size: 3GB |
| | | # 服务模块 |
| | | devtools: |
| | | restart: |
| | |
| | | profile: /home/inspection/uploadPath # 上传文件存储路径 |
| | | chunk: |
| | | path: /home/inspection/uploadPath/chunks # 切片临时目录 |
| | | zipPath: /home/inspection/uploadPath/zip # 压缩文件临时目录 |
| | |
| | | .authorizeHttpRequests((requests) -> { |
| | | permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); |
| | | // 对于登录login 注册register 验证码captchaImage 允许匿名访问 |
| | | requests.antMatchers("/login", "/register", "/captchaImage", "/ws/**","/actuator/**","/instances","/minioTransfer/**").permitAll() |
| | | requests.antMatchers("/login", "/register", "/captchaImage", "/ws/**","/actuator/**","/instances","/minioTransfer/**","/inspection/**").permitAll() |
| | | // 静态资源,可匿名访问 |
| | | .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() |
| | | .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() |
| | |
| | | <artifactId>hutool-all</artifactId> |
| | | <version>5.8.20</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework</groupId> |
| | | <artifactId>spring-webmvc</artifactId> |
| | | <version>5.3.20</version> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | |
| | | private String id; |
| | | |
| | | /** |
| | | * 点云名称 |
| | | */ |
| | | private String cloudName; |
| | | |
| | | /** |
| | | * 文件名称 |
| | | */ |
| | | private String fileName; |
| | | |
| | | /** |
| | | * 文件夹名称 |
| | | */ |
| | | private String folderName; |
| | | |
| | | /** |
| | | * 文件大小 |
| | | */ |
| | | private Long fileSize; |
| | | private String fileSize; |
| | | |
| | | /** |
| | | * 关联状态 |
| | |
| | | */ |
| | | private String groupId; |
| | | |
| | | /** |
| | | * 文件路径 |
| | | */ |
| | | private String filePath; |
| | | |
| | | } |
| New file |
| | |
| | | package com.ard.inspection.domain; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author xia |
| | | */ |
| | | @Data |
| | | public class UploadFileEntity { |
| | | |
| | | private Integer chunkNumber; |
| | | |
| | | private String fileMd5; |
| | | |
| | | private String cloudName; |
| | | |
| | | private String groupId; |
| | | |
| | | } |
| | |
| | | * @return 结果 |
| | | */ |
| | | public int deleteArdPointCloudByIds(String[] ids); |
| | | |
| | | public ArdPointCloud selectArdPointCloudByFileName(String fileName); |
| | | |
| | | } |
| | |
| | | * @return 结果 |
| | | */ |
| | | public int deleteArdPointCloudById(String id); |
| | | |
| | | public ArdPointCloud selectArdPointCloudByFileName(String filename); |
| | | |
| | | } |
| | |
| | | package com.ard.inspection.service; |
| | | |
| | | |
| | | import com.ard.common.core.domain.AjaxResult; |
| | | import com.ard.inspection.domain.UploadFileEntity; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.util.Map; |
| | |
| | | String fileMd5, |
| | | String chunkPath); |
| | | |
| | | public Map<String, Object> uploadChunk(MultipartFile file, |
| | | UploadFileEntity uploadFileEntity, |
| | | String chunkPath); |
| | | |
| | | /** |
| | | * 合并切片 |
| | | * |
| | |
| | | String fileName, |
| | | String uploadPath); |
| | | |
| | | /** |
| | | * 大文件上传并解压接口 |
| | | * @param file 上传的ZIP文件 |
| | | * @param overwrite 是否覆盖已存在文件(默认false) |
| | | * @param uploadPath 上传文件存储路径 |
| | | * @param chunkPath 临时切片存储路径 |
| | | * @param zipPath 解压文件存储路径 |
| | | * @return 上传结果 |
| | | */ |
| | | public AjaxResult uploadBigZipFile(MultipartFile file, |
| | | boolean overwrite, |
| | | String uploadPath, |
| | | String chunkPath, |
| | | String zipPath); |
| | | |
| | | } |
| | |
| | | */ |
| | | @Override |
| | | public int insertArdInspectionGroup(ArdInspectionGroup ardInspectionGroup) { |
| | | if (ardInspectionGroup.getGroupId() == null){ |
| | | if (ardInspectionGroup.getGroupParentId() == null){ |
| | | ardInspectionGroup.setGroupId((long) (ardInspectionGroupMapper.selectMaxGroupId() + 100)); |
| | | ardInspectionGroup.setGroupParentId(0L); |
| | | ardInspectionGroup.setAncestors("0"); |
| | |
| | | import java.util.List; |
| | | |
| | | import com.ard.common.utils.DateUtils; |
| | | import com.ard.common.utils.uuid.IdUtils; |
| | | import com.ard.inspection.utils.ZipFileUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import com.ard.inspection.mapper.ArdPointCloudMapper; |
| | | import com.ard.inspection.domain.ArdPointCloud; |
| | | import com.ard.inspection.service.IArdPointCloudService; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * 点云文件Service业务层处理 |
| | |
| | | |
| | | @Autowired |
| | | private ArdPointCloudMapper ardPointCloudMapper; |
| | | |
| | | @Resource |
| | | private ZipFileUtils zipFileUtils; |
| | | |
| | | /** |
| | | * 查询点云文件 |
| | |
| | | */ |
| | | @Override |
| | | public int insertArdPointCloud(ArdPointCloud ardPointCloud) { |
| | | ardPointCloud.setId(IdUtils.simpleUUID()); |
| | | ardPointCloud.setCreateTime(DateUtils.getNowDate()); |
| | | ardPointCloud.setAssociatedState("0"); |
| | | return ardPointCloudMapper.insertArdPointCloud(ardPointCloud); |
| | | } |
| | | |
| | |
| | | */ |
| | | @Override |
| | | public int deleteArdPointCloudByIds(String[] ids) { |
| | | return ardPointCloudMapper.deleteArdPointCloudByIds(ids); |
| | | // 删除点云文件 |
| | | String folderPath = "/home/inspection/uploadPath/zip/"; |
| | | int count = 0; |
| | | for (String id : ids) { |
| | | ArdPointCloud ardPointCloud = ardPointCloudMapper.selectArdPointCloudById(id); |
| | | if (zipFileUtils.deleteZipFile(folderPath + ardPointCloud.getFolderName())){ |
| | | ardPointCloudMapper.deleteArdPointCloudById(id); |
| | | count++; |
| | | } |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | /** |
| | |
| | | return ardPointCloudMapper.deleteArdPointCloudById(id); |
| | | } |
| | | |
| | | @Override |
| | | public ArdPointCloud selectArdPointCloudByFileName(String filename) { |
| | | return ardPointCloudMapper.selectArdPointCloudByFileName(filename); |
| | | } |
| | | |
| | | } |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.ard.inspection.service.impl; |
| | | |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | |
| | | @Configuration |
| | | public class StaticResourceConfig implements WebMvcConfigurer { |
| | | |
| | | @Override |
| | | public void addResourceHandlers(ResourceHandlerRegistry registry) { |
| | | // 将 /inspection/** 映射到本地 /home/inspection/uploadPath/zip/ 目录 |
| | | registry.addResourceHandler("/inspection/**") |
| | | .addResourceLocations("file:/home/inspection/uploadPath/zip/"); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.ard.inspection.utils; |
| | | |
| | | import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; |
| | | import org.apache.commons.compress.archivers.zip.ZipFile; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.io.*; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Path; |
| | | import java.nio.file.Paths; |
| | | import java.util.Comparator; |
| | | import java.util.Enumeration; |
| | | |
| | | /** |
| | | * ZIP文件解压工具类 |
| | | */ |
| | | @Component |
| | | public class ZipFileUtils { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(ZipFileUtils.class); |
| | | |
| | | @Value(value = "${inspection.chunk.zipPath}") |
| | | private String zipPath; |
| | | |
| | | /** |
| | | * 解压ZIP文件到指定目录 |
| | | * @param zipFilePath 压缩包路径 |
| | | * @param overwrite 是否覆盖已存在文件 |
| | | * @throws IOException 解压异常 |
| | | */ |
| | | public void unzip(String zipFilePath, boolean overwrite) throws IOException { |
| | | // 校验压缩包是否存在 |
| | | File zipFile = new File(zipFilePath); |
| | | if (!zipFile.exists()) { |
| | | throw new FileNotFoundException("压缩包不存在:" + zipFilePath); |
| | | } |
| | | |
| | | // 创建目标目录 |
| | | Path targetDir = Paths.get(zipPath); |
| | | if (!Files.exists(targetDir)) { |
| | | Files.createDirectories(targetDir); |
| | | } |
| | | |
| | | // 使用Apache Commons Compress处理大ZIP文件 |
| | | try (ZipFile zf = new ZipFile(zipFile)) { |
| | | Enumeration<ZipArchiveEntry> entries = zf.getEntries(); |
| | | while (entries.hasMoreElements()) { |
| | | ZipArchiveEntry entry = entries.nextElement(); |
| | | String entryName = entry.getName(); |
| | | // 拼接解压后的文件路径 |
| | | Path entryPath = targetDir.resolve(entryName); |
| | | |
| | | // 跳过已存在且不覆盖的文件 |
| | | if (Files.exists(entryPath) && !overwrite) { |
| | | log.warn("文件已存在,跳过解压:{}", entryPath); |
| | | continue; |
| | | } |
| | | |
| | | // 如果是目录,创建目录 |
| | | if (entry.isDirectory()) { |
| | | if (!Files.exists(entryPath)) { |
| | | Files.createDirectories(entryPath); |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | // 创建父目录(防止文件在子目录下) |
| | | Path parentDir = entryPath.getParent(); |
| | | if (!Files.exists(parentDir)) { |
| | | Files.createDirectories(parentDir); |
| | | } |
| | | |
| | | // 流式复制文件(避免内存溢出) |
| | | try (InputStream in = zf.getInputStream(entry); |
| | | OutputStream out = Files.newOutputStream(entryPath)) { |
| | | byte[] buffer = new byte[8192]; // 8K缓冲区 |
| | | int len; |
| | | while ((len = in.read(buffer)) != -1) { |
| | | out.write(buffer, 0, len); |
| | | } |
| | | log.info("解压文件完成:{}", entryPath); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("解压文件失败:{}", zipFilePath, e); |
| | | throw new IOException("解压失败:" + e.getMessage(), e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 解压ZIP文件到指定目录 |
| | | * @param pathStr 删除文件夹路径 |
| | | */ |
| | | public boolean deleteZipFile(String pathStr) { |
| | | if (pathStr == null || pathStr.isEmpty()) { |
| | | return false; |
| | | } |
| | | Path path = Paths.get(pathStr); |
| | | if (!Files.exists(path)) { |
| | | // 路径不存在,视为删除成功 |
| | | return true; |
| | | } |
| | | try { |
| | | // 遍历并反向排序,确保先删除子文件/子目录,再删除父目录 |
| | | Files.walk(path) |
| | | .sorted(Comparator.reverseOrder()) |
| | | .forEach(p -> { |
| | | try { |
| | | Files.deleteIfExists(p); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException("删除失败: " + p, e); |
| | | } |
| | | }); |
| | | return true; |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据文件大小格式化 |
| | | * @param size 文件大小 |
| | | */ |
| | | public static String formatFileSize(long size) { |
| | | if (size <= 0) return "0 B"; |
| | | final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"}; |
| | | int digitGroups = (int) (Math.log10(size) / Math.log10(1024)); |
| | | return String.format("%.2f %s", size / Math.pow(1024, digitGroups), units[digitGroups]); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | <select id="checkInspectionGroupNameUniqueB" resultMap="ArdInspectionGroupResult"> |
| | | <include refid="selectArdInspectionGroupVo"/> |
| | | where group_name=#{groupName} limit 1 |
| | | where del_flag = '0' |
| | | and group_name=#{groupName} limit 1 |
| | | </select> |
| | | |
| | | <select id="selectChildrenInspectionGroupById" parameterType="Long" resultMap="ArdInspectionGroupResult"> |
| | |
| | | |
| | | <resultMap type="ArdPointCloud" id="ArdPointCloudResult"> |
| | | <result property="id" column="id" /> |
| | | <result property="cloudName" column="cloud_name" /> |
| | | <result property="fileName" column="file_name" /> |
| | | <result property="folderName" column="folder_name" /> |
| | | <result property="fileSize" column="file_size" /> |
| | | <result property="associatedState" column="associated_state" /> |
| | | <result property="routeId" column="route_id" /> |
| | |
| | | <result property="createTime" column="create_time" /> |
| | | <result property="updateBy" column="update_by" /> |
| | | <result property="updateTime" column="update_time" /> |
| | | <result property="filePath" column="file_path" /> |
| | | </resultMap> |
| | | |
| | | <sql id="selectArdPointCloudVo"> |
| | | select id, |
| | | cloud_name, |
| | | file_name, |
| | | folder_name, |
| | | file_size, |
| | | associated_state, |
| | | route_id, |
| | |
| | | create_by, |
| | | create_time, |
| | | update_by, |
| | | update_time |
| | | update_time, |
| | | file_path |
| | | from ard_point_cloud |
| | | </sql> |
| | | |
| | | <select id="selectArdPointCloudList" parameterType="ArdPointCloud" resultMap="ArdPointCloudResult"> |
| | | <include refid="selectArdPointCloudVo"/> |
| | | <where> |
| | | <if test="cloudName != null and cloudName != ''"> and cloud_name like concat('%', #{cloudName}, '%')</if> |
| | | <if test="fileName != null and fileName != ''"> and file_name like concat('%', #{fileName}, '%')</if> |
| | | <if test="fileSize != null "> and file_size = #{fileSize}</if> |
| | | <if test="associatedState != null and associatedState != ''"> and associated_state = #{associatedState}</if> |
| | | <if test="routeId != null and routeId != ''"> and route_id = #{routeId}</if> |
| | | <if test="groupId != null and groupId != ''"> and group_id = #{groupId}</if> |
| | | <if test="createBy != null and createBy != ''"> and create_by = #{createBy}</if> |
| | | <if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 --> |
| | | and date_format(create_time,'%Y%m%d') >= date_format(#{params.beginTime},'%Y%m%d') |
| | | </if> |
| | | <if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 --> |
| | | and date_format(create_time,'%Y%m%d') <= date_format(#{params.endTime},'%Y%m%d') |
| | | </if> |
| | | </where> |
| | | </select> |
| | | |
| | |
| | | insert into ard_point_cloud |
| | | <trim prefix="(" suffix=")" suffixOverrides=","> |
| | | <if test="id != null">id,</if> |
| | | <if test="cloudName != null">cloud_name,</if> |
| | | <if test="fileName != null">file_name,</if> |
| | | <if test="folderName != null">folder_name,</if> |
| | | <if test="fileSize != null">file_size,</if> |
| | | <if test="associatedState != null">associated_state,</if> |
| | | <if test="routeId != null">route_id,</if> |
| | |
| | | <if test="createTime != null">create_time,</if> |
| | | <if test="updateBy != null">update_by,</if> |
| | | <if test="updateTime != null">update_time,</if> |
| | | <if test="filePath != null">file_path,</if> |
| | | </trim> |
| | | <trim prefix="values (" suffix=")" suffixOverrides=","> |
| | | <if test="id != null">#{id},</if> |
| | | <if test="cloudName != null">#{cloudName},</if> |
| | | <if test="fileName != null">#{fileName},</if> |
| | | <if test="folderName != null">#{folderName},</if> |
| | | <if test="fileSize != null">#{fileSize},</if> |
| | | <if test="associatedState != null">#{associatedState},</if> |
| | | <if test="routeId != null">#{routeId},</if> |
| | |
| | | <if test="createTime != null">#{createTime},</if> |
| | | <if test="updateBy != null">#{updateBy},</if> |
| | | <if test="updateTime != null">#{updateTime},</if> |
| | | <if test="filePath != null">#{filePath},</if> |
| | | </trim> |
| | | </insert> |
| | | |
| | | <update id="updateArdPointCloud" parameterType="ArdPointCloud"> |
| | | update ard_point_cloud |
| | | <trim prefix="SET" suffixOverrides=","> |
| | | <if test="cloudName != null">cloud_name = #{cloudName},</if> |
| | | <if test="fileName != null">file_name = #{fileName},</if> |
| | | <if test="folderName != null">folder_name = #{folderName},</if> |
| | | <if test="fileSize != null">file_size = #{fileSize},</if> |
| | | <if test="associatedState != null">associated_state = #{associatedState},</if> |
| | | <if test="routeId != null">route_id = #{routeId},</if> |
| | |
| | | <if test="createTime != null">create_time = #{createTime},</if> |
| | | <if test="updateBy != null">update_by = #{updateBy},</if> |
| | | <if test="updateTime != null">update_time = #{updateTime},</if> |
| | | <if test="filePath != null">file_path = #{filePath},</if> |
| | | </trim> |
| | | where id = #{id} |
| | | </update> |
| | |
| | | </foreach> |
| | | </delete> |
| | | |
| | | <select id="selectArdPointCloudByFileName" parameterType="String" resultMap="ArdPointCloudResult"> |
| | | <include refid="selectArdPointCloudVo"/> |
| | | where file_name = #{fileName} |
| | | </select> |
| | | |
| | | </mapper> |