208 lines
8.8 KiB
Java
208 lines
8.8 KiB
Java
package com.ruoyi.airline.service.impl;
|
||
|
||
import com.ruoyi.airline.domain.api.IAirlineFileDomain;
|
||
import com.ruoyi.airline.domain.model.AirlineFile;
|
||
import com.ruoyi.airline.domain.model.kml.KmlInfo;
|
||
import com.ruoyi.airline.domain.uitl.KmlFileUtils;
|
||
import com.ruoyi.airline.domain.uitl.WayPointUitls;
|
||
import com.ruoyi.airline.service.api.IAirlineFileService;
|
||
import com.ruoyi.airline.service.convert.AirlineFileServiceConvert;
|
||
import com.ruoyi.airline.service.dto.AirLinePointDTO;
|
||
import com.ruoyi.airline.service.dto.AirlineFileDTO;
|
||
import com.ruoyi.common.core.domain.R;
|
||
import com.ruoyi.common.core.exception.base.BaseException;
|
||
import com.ruoyi.common.core.utils.file.FileUtils;
|
||
import com.ruoyi.system.api.RemoteFileService;
|
||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||
import org.apache.commons.compress.archivers.ArchiveInputStream;
|
||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||
import org.slf4j.Logger;
|
||
import org.slf4j.LoggerFactory;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.web.multipart.MultipartFile;
|
||
|
||
import java.io.IOException;
|
||
import java.util.Arrays;
|
||
import java.util.List;
|
||
import java.util.Objects;
|
||
import java.util.UUID;
|
||
|
||
/**
|
||
* 航线文件Service实现类
|
||
*
|
||
* @author ruoyi
|
||
* @date 2026-01-17
|
||
*/
|
||
@Service
|
||
public class AirlineFileServiceImpl implements IAirlineFileService {
|
||
|
||
private static final Logger log = LoggerFactory.getLogger(AirlineFileServiceImpl.class);
|
||
|
||
@Autowired
|
||
private RemoteFileService remoteFileService;
|
||
|
||
@Autowired
|
||
private IAirlineFileDomain iAirlineFileDomain;
|
||
|
||
|
||
@Override
|
||
public AirlineFileDTO save(AirlineFileDTO dto) {
|
||
AirlineFile model = AirlineFileServiceConvert.to(dto);
|
||
Long id = iAirlineFileDomain.save(model);
|
||
dto.setId(id);
|
||
return dto;
|
||
}
|
||
|
||
|
||
/**
|
||
* 上传航线文件,如果是KMZ的需要转换成 waypoint 的,并且需要将 原始航线文件保存。
|
||
* 并且限制航线修改,因为暂时没做到 从waypoingt 转 KMZ
|
||
*
|
||
* @param file
|
||
* @param groupId
|
||
* @return
|
||
*/
|
||
@Override
|
||
public AirlineFileDTO parseAndUplload(MultipartFile file, Long groupId) {
|
||
|
||
String originalFilename = file.getOriginalFilename();
|
||
String fileExtension = "";
|
||
if (originalFilename != null && originalFilename.lastIndexOf('.') > 0) {
|
||
fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.') + 1).toLowerCase();
|
||
}
|
||
int pos = 0;
|
||
if (originalFilename != null) {
|
||
pos = originalFilename.lastIndexOf(".");
|
||
}
|
||
String fileNameWithoutExtension = pos > 0 ? originalFilename.substring(0, pos) : originalFilename;
|
||
String newFileName = getNewFileNameLikeByGroupId(fileNameWithoutExtension, groupId);
|
||
log.info("filename :{}, new filename :{}",fileNameWithoutExtension, newFileName);
|
||
try {
|
||
if ("zip".equals(fileExtension) || "kmz".equals(fileExtension)) {
|
||
// 处理ZIP/KMZ文件
|
||
KmlInfo kmlInfo = new KmlInfo();
|
||
try (ArchiveInputStream archiveInputStream = new ZipArchiveInputStream(file.getInputStream());) {
|
||
ArchiveEntry entry;
|
||
while (!Objects.isNull(entry = archiveInputStream.getNextEntry())) {
|
||
String name = entry.getName();
|
||
if (name.toLowerCase().endsWith(".kml")) {
|
||
// 解KML文件
|
||
kmlInfo = KmlFileUtils.parseKml(archiveInputStream);
|
||
}
|
||
}
|
||
|
||
if (Objects.isNull(kmlInfo)) {
|
||
throw new BaseException("kmz文件内容缺失");
|
||
}
|
||
String globalHeight = kmlInfo.getDocument().getFolder().getGlobalHeight();
|
||
AirlineFileDTO dto = new AirlineFileDTO();
|
||
// 去除文件名中的后缀名
|
||
dto.setName(newFileName);
|
||
dto.setFileName(originalFilename);
|
||
R<String> fileUrl = remoteFileService.uploadFileByData(UUID.randomUUID().toString(), "waypoints", WayPointUitls.kmz2waypoint(kmlInfo));
|
||
dto.setFileUrl(fileUrl.getData());
|
||
dto.setType(kmlInfo.getDocument().getFolder().getTemplateType());
|
||
// TODO 大疆默认1,后续想办法优化成表格破诶中
|
||
String airVendor = "1";
|
||
String airType = kmlInfo.getDocument().getKmlMissionConfig().getDroneInfo().getDroneEnumValue();
|
||
String airSubType = kmlInfo.getDocument().getKmlMissionConfig().getDroneInfo().getDroneSubEnumValue();
|
||
dto.setAirVendor(airVendor);
|
||
// 无人机的领域默认为0
|
||
dto.setAirType(String.format("0-%s-%s", airType, airSubType));
|
||
return dto;
|
||
}
|
||
} else if ("waypoints".equals(fileExtension)) {
|
||
// 直接处理Waypoints文件
|
||
AirlineFileDTO dto = new AirlineFileDTO();
|
||
// 去除文件名中的后缀名
|
||
dto.setName(newFileName);
|
||
dto.setFileName(originalFilename);
|
||
// 直接读取文件内容并上传
|
||
R<String> fileUrl = remoteFileService.uploadFileByData(UUID.randomUUID().toString(), "waypoints", new String(file.getBytes()));
|
||
dto.setFileUrl(fileUrl.getData());
|
||
// TODO 拓恒默认0,后续想办法优化成表格破诶中
|
||
String airVendor = "0";
|
||
String airType = "0";
|
||
String airSubType = "1"; // 默认Fm003,的type为1
|
||
dto.setAirVendor(airVendor);
|
||
// 无人机的领域默认为0
|
||
dto.setAirType(String.format("0-%s-%s", airType, airSubType));
|
||
|
||
return dto;
|
||
} else {
|
||
throw new BaseException("不支持的文件格式,请上传KMZ或Waypoints文件");
|
||
}
|
||
} catch (IOException e) {
|
||
throw new BaseException("文件处理失败");
|
||
} catch (Exception e) {
|
||
log.error("航线文件处理失败", e);
|
||
throw new BaseException("航线文件处理失败");
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 航点编辑,直接将大疆KMZ转换成waypoints操作,就不需要区分大疆还是拓恒了
|
||
*
|
||
* @param airlineFile 航线文件dto
|
||
* @return
|
||
*/
|
||
@Override
|
||
public AirlineFileDTO createOrupdate(AirlineFileDTO airlineFile) {
|
||
|
||
StringBuilder waypointBuilder = new StringBuilder("QGC WPL 110\n");
|
||
List<AirLinePointDTO> LineDto = airlineFile.getLinePointDtoList();
|
||
// 新建字节输出流,Freemarker操作此输出流写入生成的业务文件.
|
||
if (LineDto != null && !LineDto.isEmpty()) {
|
||
for (int i = 0; i < LineDto.size(); i++) {
|
||
AirLinePointDTO point = LineDto.get(i);
|
||
waypointBuilder.append(WayPointUitls.formatWaypointLine(point, i)).append("\n");
|
||
}
|
||
|
||
// 上传文件
|
||
R<String> fileUrl = remoteFileService.uploadFileByData(UUID.randomUUID().toString(), "waypoints", waypointBuilder.toString());
|
||
|
||
//保存航线文件数据
|
||
airlineFile.setFileUrl(fileUrl.getData());
|
||
airlineFile.setSource("airport");
|
||
airlineFile.setStatus(airlineFile.getStatus() == null ? 1 : airlineFile.getStatus());
|
||
AirlineFile model = AirlineFileServiceConvert.to(airlineFile);
|
||
Long id = iAirlineFileDomain.save(model);
|
||
model.setId(id);
|
||
return AirlineFileServiceConvert.from(model);
|
||
}
|
||
return null;
|
||
|
||
}
|
||
|
||
|
||
@Override
|
||
public AirlineFileDTO selectById(Long airlineId) {
|
||
if (airlineId == null) {
|
||
return null;
|
||
}
|
||
List<Long> ids = List.of(airlineId);
|
||
List<AirlineFile> airlineFiles = iAirlineFileDomain.selectFileListByIds(ids);
|
||
List<AirlineFileDTO> airlineFilesDTO = AirlineFileServiceConvert.fromList(airlineFiles);
|
||
return airlineFilesDTO != null && !airlineFilesDTO.isEmpty() ? airlineFilesDTO.get(0) : null;
|
||
}
|
||
|
||
@Override
|
||
public String getNewFileNameLikeByGroupId(String name, Long groupId) {
|
||
|
||
List<AirlineFile> airlineFiles = iAirlineFileDomain.selectFileNameLikeByGroupId(name, groupId);
|
||
String newFileName = name;
|
||
if (airlineFiles != null && !airlineFiles.isEmpty()) {
|
||
List<String> fileNames = airlineFiles.stream().map(AirlineFile::getName).toList();
|
||
newFileName = FileUtils.generateUniqueFileName(name, fileNames);
|
||
}
|
||
|
||
return newFileName;
|
||
}
|
||
|
||
@Override
|
||
public Long update(AirlineFileDTO dto) {
|
||
AirlineFile model = AirlineFileServiceConvert.to(dto);
|
||
return iAirlineFileDomain.update(model);
|
||
}
|
||
} |