[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