[add] 新增无人机模块后端项目
[refactor] 重构后端项目
This commit is contained in:
		| @ -0,0 +1,350 @@ | ||||
| package com.ruoyi.wayline.controller; | ||||
|  | ||||
| import com.ruoyi.system.domain.FlightPaths; | ||||
| import com.ruoyi.system.domain.ManageDeviceDictionary; | ||||
| import com.ruoyi.system.service.IFlightPathsService; | ||||
| import com.ruoyi.system.service.IManageDeviceDictionaryService; | ||||
| import com.ruoyi.wayline.domain.AddWaypointVo; | ||||
| import com.ruoyi.wayline.domain.RenameVo; | ||||
| import com.ruoyi.wayline.domain.WaypointData; | ||||
| import com.ruoyi.wayline.utils.HttpResult; | ||||
| import com.ruoyi.wayline.utils.MD5Util; | ||||
| import com.ruoyi.wayline.waypoint.WayPointKmlProcessorModify; | ||||
| import com.ruoyi.wayline.waypoint.WayPointWpmlProcessorModify; | ||||
| import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiOperation; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.core.env.Environment; | ||||
| import org.springframework.http.*; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.multipart.MultipartFile; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import java.io.*; | ||||
| import java.net.InetAddress; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.nio.file.*; | ||||
| import java.security.MessageDigest; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.util.*; | ||||
| import java.util.zip.*; | ||||
|  | ||||
| @Slf4j | ||||
| @RestController | ||||
| @Api(tags = "航线文件管理") | ||||
| public class WaypointController { | ||||
|  | ||||
|     @Resource | ||||
|     private IFlightPathsService flightPathsService; | ||||
|     @Resource | ||||
|     private IManageDeviceDictionaryService manageDeviceDictionaryService; | ||||
|     @Resource | ||||
|     private Environment environment; | ||||
|  | ||||
|     private static final String UPLOAD_DIR = System.getProperty("user.dir") + "/upload"; | ||||
|  | ||||
|     // 工具方法:使用 flag 和 fileName 组合计算 MD5 值 | ||||
|     private String calculateMD5(String flag, String fileName) { | ||||
|         String input = flag + fileName; | ||||
|         MessageDigest md = null; | ||||
|         try { | ||||
|             md = MessageDigest.getInstance("MD5"); | ||||
|         } catch (NoSuchAlgorithmException e) { | ||||
|             throw new RuntimeException(e); | ||||
|         } | ||||
|         byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8)); | ||||
|         StringBuilder sb = new StringBuilder(); | ||||
|         for (byte b : digest) sb.append(String.format("%02x", b)); | ||||
|         log.info("MD5: {}", sb.toString()); | ||||
|         return sb.toString(); | ||||
|     } | ||||
|  | ||||
|     // 工具方法:检查文件是否已存在并返回错误信息 | ||||
|     private ResponseEntity<HttpResult> checkFileExistence(String fileName, String flag) { | ||||
|         FlightPaths flightPaths = new FlightPaths(); | ||||
|         flightPaths.setFileName(fileName); | ||||
|         flightPaths.setFlag(flag); | ||||
|         List<FlightPaths> pathsList = flightPathsService.selectByCondition(flightPaths); | ||||
|         if (pathsList != null && !pathsList.isEmpty()) { | ||||
|             HttpResult httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("文件名重复,请重新命名"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     private boolean checkFileExistenceWithBool(String fileName, String flag) { | ||||
|         FlightPaths flightPaths = new FlightPaths(); | ||||
|         flightPaths.setFileName(fileName); | ||||
|         flightPaths.setFlag(flag); | ||||
|         List<FlightPaths> pathsList = flightPathsService.selectByCondition(flightPaths); | ||||
|         return pathsList != null && !pathsList.isEmpty(); | ||||
|     } | ||||
|  | ||||
|     @ApiOperation("导入航线文件") | ||||
|     @PostMapping("/dj/router/import") | ||||
|     public ResponseEntity<HttpResult> importWaypoint(@RequestParam("file") MultipartFile file, @RequestParam("flag") String flag) { | ||||
|         if (file.isEmpty()) { | ||||
|             HttpResult httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("文件为空"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             String fileName = file.getOriginalFilename(); | ||||
|             ResponseEntity<HttpResult> existenceCheck = checkFileExistence(fileName, flag); | ||||
|             if (existenceCheck != null) return existenceCheck; | ||||
|  | ||||
|             // 创建上传目录 | ||||
|             Path uploadPath = Paths.get(UPLOAD_DIR); | ||||
|             Files.createDirectories(uploadPath); | ||||
|  | ||||
|             byte[] fileBytes = file.getBytes(); | ||||
|             String md5 = calculateMD5(flag, fileName);  // 使用 flag 和 fileName 组合生成 MD5 | ||||
|             String md5FileNameWithExtension = md5 + ".kmz"; | ||||
|             Path serverPath = uploadPath.resolve(md5FileNameWithExtension); | ||||
|  | ||||
|             Files.write(serverPath, fileBytes); | ||||
|  | ||||
|             String downloadLink = buildDownloadLink(md5FileNameWithExtension); | ||||
|             saveFlightPath(fileName, flag, md5, downloadLink, true); | ||||
|  | ||||
|             HttpResult httpResult = HttpResult.ok(); | ||||
|             httpResult.setMessage("文件导入成功"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } catch (Exception e) { | ||||
|             log.error("文件保存失败: {}", e.getMessage()); | ||||
|             HttpResult httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("保存失败"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void saveFlightPath(String fileName, String flag, String md5, String fileUrl, boolean isImport) { | ||||
|         FlightPaths flightPath = new FlightPaths(); | ||||
|         flightPath.setFileName(fileName); | ||||
|         flightPath.setFlag(flag); | ||||
|         flightPath.setFileMd5(md5); | ||||
|         flightPath.setFileUrl(fileUrl); | ||||
|         flightPath.setIsImport(isImport ? "true" : "false"); | ||||
|         flightPath.setCreatedAt(new Date()); | ||||
|         flightPath.setUpdatedAt(new Date()); | ||||
|         flightPathsService.insertFlightPaths(flightPath); | ||||
|     } | ||||
|  | ||||
|     private String buildDownloadLink(String md5FileNameWithExtension) throws IOException { | ||||
|         String ip = environment.getProperty("server.host", InetAddress.getLocalHost().getHostAddress()); | ||||
|         int port = environment.getProperty("server.port", Integer.class, 8080); | ||||
|         return "http://" + ip + ":" + port + "/dj/router/download/" + md5FileNameWithExtension; | ||||
|     } | ||||
|  | ||||
|     @ApiOperation("新增航线文件") | ||||
|     @PostMapping("/dj/router/add") | ||||
|     public ResponseEntity<HttpResult> addWaypoint(@RequestBody AddWaypointVo addWaypointVo) { | ||||
|         ResponseEntity<HttpResult> existenceCheck = checkFileExistence(addWaypointVo.getFilename(), addWaypointVo.getFlag()); | ||||
|         if (existenceCheck != null) return existenceCheck; | ||||
|  | ||||
|         FlightPaths flightPaths = new FlightPaths(); | ||||
|         flightPaths.setFileName(addWaypointVo.getFilename()); | ||||
|         flightPaths.setFlag(addWaypointVo.getFlag()); | ||||
|         flightPaths.setIsImport("false"); | ||||
|         flightPaths.setGlobalPointHeight(addWaypointVo.getGlobalPointHeight()); | ||||
|         flightPaths.setCreatedAt(new Date()); | ||||
|         flightPaths.setUpdatedAt(new Date()); | ||||
|  | ||||
|         // 获取飞机类型 | ||||
|         String[] split = addWaypointVo.getRemark().split("-"); | ||||
|         ManageDeviceDictionary manageDeviceDictionary = manageDeviceDictionaryService | ||||
|                 .selectManageDeviceDictionaryByCondition(split[0], split[1], split[2]); | ||||
|         flightPaths.setDeviceType(manageDeviceDictionary.getDeviceName()); | ||||
|  | ||||
|         flightPathsService.insertFlightPaths(flightPaths); | ||||
|         return ResponseEntity.ok(HttpResult.ok()); | ||||
|     } | ||||
|  | ||||
|     @ApiOperation("根据参数追数据到加航线文件") | ||||
|     @PostMapping("/dj/router/waypoint") | ||||
|     public ResponseEntity<HttpResult> downloadWaypoint(@RequestBody WaypointData dataRequest) { | ||||
|         HttpResult httpResult = HttpResult.ok(); | ||||
|         Map<String, Object> map = new HashMap<>(); | ||||
|         String fileName = flightPathsService.selectFlightPathsById(Long.valueOf(dataRequest.getId())).getFileName(); | ||||
|         Path uploadPath = Paths.get(UPLOAD_DIR); | ||||
|  | ||||
|         try { | ||||
|             Files.createDirectories(uploadPath); | ||||
|             String md5FileName = calculateMD5(dataRequest.getFlag(), fileName);  // 使用 flag 和 fileName 组合生成 MD5 | ||||
|             String md5FileNameWithExtension = md5FileName + ".kmz"; | ||||
|             Path serverPath = uploadPath.resolve(md5FileNameWithExtension); | ||||
|  | ||||
|             // 日志:显示生成的文件路径 | ||||
|             log.info("下载航线文件路径: {}", serverPath); | ||||
|  | ||||
|             // 创建并压缩文件 | ||||
|             try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); | ||||
|                  ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) { | ||||
|  | ||||
|                 byte[] file1 = new WayPointKmlProcessorModify().processKml(dataRequest, new Random().nextInt(9000) + 1000); | ||||
|                 zipOut.putNextEntry(new ZipEntry("wpmz/template.kml")); | ||||
|                 zipOut.write(file1); | ||||
|                 zipOut.closeEntry(); | ||||
|  | ||||
|                 byte[] file2 = new WayPointWpmlProcessorModify().processWpml(dataRequest, new Random().nextInt(9000) + 1000); | ||||
|                 zipOut.putNextEntry(new ZipEntry("wpmz/waylines.wpml")); | ||||
|                 zipOut.write(file2); | ||||
|                 zipOut.closeEntry(); | ||||
|  | ||||
|                 zipOut.finish(); | ||||
|                 Files.write(serverPath, byteArrayOutputStream.toByteArray()); | ||||
|             } | ||||
|  | ||||
|             // 构建下载链接并更新数据库 | ||||
|             String downloadLink = buildDownloadLink(md5FileNameWithExtension); | ||||
|             map.put("downloadLink", downloadLink); | ||||
|             map.put("flag", true); | ||||
|             map.put("signature", md5FileName); | ||||
|             httpResult.setData(map); | ||||
|             httpResult.setMessage("生成航线文件并转存至服务器成功!"); | ||||
|  | ||||
|             // 更新数据库中的航线文件记录,保存生成的MD5值 | ||||
|             FlightPaths flightPaths = new FlightPaths(); | ||||
|             flightPaths.setId(Long.valueOf(dataRequest.getId())); | ||||
|             flightPaths.setFileName(fileName); | ||||
|             flightPaths.setFileUrl(downloadLink); | ||||
|             flightPaths.setFileMd5(md5FileName);  // 存储 MD5 值 | ||||
|             flightPaths.setPhotoNum(Long.valueOf(dataRequest.getPhotoNum())); | ||||
|             flightPaths.setEstimateTime(dataRequest.getEstimateTime()); | ||||
|             flightPaths.setType(dataRequest.getType()); | ||||
|             flightPaths.setWaylineLen(dataRequest.getWaylineLen()); | ||||
|             flightPaths.setPoints(dataRequest.getPoints()); | ||||
|             flightPaths.setUpdatedAt(new Date()); | ||||
|             flightPathsService.updateFlightPaths(flightPaths); | ||||
|  | ||||
|         } catch (Exception e) { | ||||
|             httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("生成航线文件并转存至服务器失败,原因:" + e.getMessage()); | ||||
|         } | ||||
|         return ResponseEntity.ok(httpResult); | ||||
|     } | ||||
|  | ||||
|     @ApiOperation("下载航线文件") | ||||
|     @GetMapping("/dj/router/download/{fileName}") | ||||
|     public ResponseEntity<byte[]> downloadFile(@PathVariable String fileName) { | ||||
|         Path filePath = Paths.get(UPLOAD_DIR, fileName); | ||||
|         if (!Files.exists(filePath)) { | ||||
|             return ResponseEntity.notFound().build(); | ||||
|         } | ||||
|         try { | ||||
|             byte[] fileContent = Files.readAllBytes(filePath); | ||||
|             HttpHeaders headers = new HttpHeaders(); | ||||
|             headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); | ||||
|             headers.setContentDisposition(ContentDisposition.builder("attachment").filename(fileName, StandardCharsets.UTF_8).build()); | ||||
|             return ResponseEntity.ok().headers(headers).body(fileContent); | ||||
|         } catch (IOException e) { | ||||
|             log.error("文件下载失败, 原因: {}", e.getMessage()); | ||||
|             return ResponseEntity.status(500).build(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @ApiOperation("复制航线文件") | ||||
|     @PostMapping("/dj/router/copy/{id}") | ||||
|     public ResponseEntity<HttpResult> copyWaypoint(@PathVariable Long id) { | ||||
|         FlightPaths originalFlightPaths = flightPathsService.selectFlightPathsById(id); | ||||
|         if (originalFlightPaths == null) return ResponseEntity.notFound().build(); | ||||
|  | ||||
|         String originalFileName = originalFlightPaths.getFileName(); | ||||
|         String originalMd5 = originalFlightPaths.getFileMd5(); | ||||
|         Path originalFilePath = Paths.get(UPLOAD_DIR, originalMd5 + ".kmz"); | ||||
|  | ||||
|         // 日志:显示待复制的原始文件路径 | ||||
|         log.info("复制航线文件路径: {}", originalFilePath); | ||||
|  | ||||
|         if (!Files.exists(originalFilePath)) { | ||||
|             HttpResult httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("请先生成航线文件再执行复制"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|  | ||||
|         String newFileName = originalFileName + "(1)"; | ||||
|  | ||||
|         // 查询文件是否已存在 | ||||
|         if (checkFileExistenceWithBool(newFileName, originalFlightPaths.getFlag())) { | ||||
|             HttpResult httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("航线文件" + newFileName + "已存在"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|  | ||||
|         String newMd5 = calculateMD5(originalFlightPaths.getFlag(), newFileName); | ||||
|         Path newFilePath = Paths.get(UPLOAD_DIR, newMd5 + ".kmz"); | ||||
|  | ||||
|         try { | ||||
|             Files.copy(originalFilePath, newFilePath); | ||||
|             FlightPaths newFlightPaths = new FlightPaths(); | ||||
|             newFlightPaths.setFileName(newFileName); | ||||
|             newFlightPaths.setFileUrl(buildDownloadLink(newMd5 + ".kmz")); | ||||
|             newFlightPaths.setFileMd5(newMd5); | ||||
|             newFlightPaths.setFlag(originalFlightPaths.getFlag()); | ||||
|             newFlightPaths.setIsImport(originalFlightPaths.getIsImport()); | ||||
|             newFlightPaths.setPoints(originalFlightPaths.getPoints()); | ||||
|             newFlightPaths.setDeviceType(originalFlightPaths.getDeviceType()); | ||||
|             newFlightPaths.setPhotoNum(originalFlightPaths.getPhotoNum()); | ||||
|             newFlightPaths.setEstimateTime(originalFlightPaths.getEstimateTime()); | ||||
|             newFlightPaths.setType(originalFlightPaths.getType()); | ||||
|             newFlightPaths.setWaylineLen(originalFlightPaths.getWaylineLen()); | ||||
|             newFlightPaths.setRemark(originalFlightPaths.getRemark()); | ||||
|  | ||||
|             newFlightPaths.setCreatedAt(new Date()); | ||||
|             newFlightPaths.setUpdatedAt(new Date()); | ||||
|  | ||||
|             flightPathsService.insertFlightPaths(newFlightPaths); | ||||
|  | ||||
|             HttpResult httpResult = HttpResult.ok(); | ||||
|             httpResult.setMessage("复制航线文件成功!"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } catch (IOException e) { | ||||
|             HttpResult httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("复制航线文件失败, 原因:" + e.getMessage()); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @ApiOperation("重命名航线文件") | ||||
|     @PostMapping("/dj/router/rename") | ||||
|     public ResponseEntity<HttpResult> renameWaypoint(@RequestBody RenameVo renameVo) { | ||||
|         FlightPaths flightPaths = flightPathsService.selectFlightPathsById(renameVo.getId()); | ||||
|         if (flightPaths == null) return ResponseEntity.notFound().build(); | ||||
|  | ||||
|         // 如果文件名称和现在已有的名称相同则不进行任何处理 | ||||
|         if (flightPaths.getFileName().equals(renameVo.getNewFileName())) { | ||||
|             HttpResult httpResult = HttpResult.ok(); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|         if (checkFileExistenceWithBool(renameVo.getNewFileName(), flightPaths.getFlag())) { | ||||
|             HttpResult httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("航线文件" + renameVo.getNewFileName() + "已存在,请重新命名"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|  | ||||
|         String newMd5 = calculateMD5(flightPaths.getFlag(), renameVo.getNewFileName()); | ||||
|         String originalMd5 = flightPaths.getFileMd5(); | ||||
|         Path originalFilePath = Paths.get(UPLOAD_DIR, originalMd5 + ".kmz"); | ||||
|         Path newFilePath = Paths.get(UPLOAD_DIR, newMd5 + ".kmz"); | ||||
|  | ||||
|         try { | ||||
|             Files.move(originalFilePath, newFilePath); | ||||
|             flightPaths.setFileName(renameVo.getNewFileName()); | ||||
|             flightPaths.setFileUrl(buildDownloadLink(newMd5 + ".kmz")); | ||||
|             flightPaths.setFileMd5(newMd5); | ||||
|             flightPaths.setGlobalPointHeight(flightPaths.getGlobalPointHeight()); | ||||
|             flightPaths.setUpdatedAt(new Date()); | ||||
|             flightPathsService.updateFlightPaths(flightPaths); | ||||
|  | ||||
|             HttpResult httpResult = HttpResult.ok(); | ||||
|             httpResult.setMessage("重命名航线文件成功!"); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } catch (IOException e) { | ||||
|             HttpResult httpResult = HttpResult.error(); | ||||
|             httpResult.setMessage("重命名航线文件失败, 原因: " + e.getMessage()); | ||||
|             return ResponseEntity.ok(httpResult); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user